Mixins are not inherited?

Jonathan M Davis jmdavisProg at gmx.com
Thu May 3 14:55:23 PDT 2012


On Thursday, May 03, 2012 23:32:50 Namespace wrote:
> By the following code i get these error messages:
> 
> ----
> Error: template RefTest.Ref.__unittest1.instanceof(T : Object,U :
> Object) cannot deduce template function from argument types
> !(A)(B)
> 
> Error: template RefTest.Ref.__unittest1.instanceof does not match
> any function template declaration
> 
> Error: template instance instanceof!(A) errors instantiating
> template
> ----
> 
> How is this possible? I thougth that the mixin would be inherited
> and so every subclass would be implicit cast to his super type.
> Isn't that so?
> If i write "mixin TRef!(B);" in class B, it works fine. Can
> anyone explain me why do i have to write it in class B?
> 
> [code]
> unittest {
> bool instanceof(T : Object, U : Object)(const Ref!U obj) {
> const U o = obj.access;
> 
> return const_cast(o).toString() == typeid(T).toString();
> }
> 
> class A {
> mixin TRef!(A);
> }
> 
> class B : A {
> //mixin TRef!(B);
> }
> 
> class C : B {
> //mixin TRef!(C);
> }
> 
> A a1 = new B();
> A a2 = new C();
> 
> assert(instanceof!(A)(a1) == false);
> assert(instanceof!(B)(a1));
> assert(instanceof!(C)(a1) == false);
> 
> writeln(a1);
> 
> B b1 = cast(B) a1;
> 
> assert(instanceof!(A)(b1) == false); // <-- fails
> 
> writeln(b1);
> 
> writeln();
> }
> [/code]
> 
> "TRef" is the same mixin template and "Ref" the same template
> struct as in my last threads.

Nothing you put in a base class is automatically in a derived class. If you 
put a member variable or member function in a base class, it's not in the 
derived class. It's just that the derived class has access to it as long as 
it's protected or public.

In the case of a mixin, you're essentially copying and pasting code. So, it's 
in the base class similarly to if you typed it there yourself. However, 
templated functions aren't virtual, so unlike if you typed them yourself, they 
won't be virtual if you use a template mixin.

So, if you want to mixin something into every class in a hierarchy, you must 
mix it in to every class in the hierarchy, not just the base class.

And if you want to test whether an object is an instance of a specific class, 
then cast it and check whether the result is null. You don't need to create a 
function to figure it out for you. e.g.

auto c = cast(MyClass)object;
if(c is null)
 writeln("c is NOT an instance of MyClass");
else
 writeln("c IS an instance of MyClass");

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list