Tim M wrote:
What I was trying to say is that func needs to be called with an "A" but
calling it with a "B" works because a "B" is a kind of "A". The function
looses an information that it is a "B" returns it as an "A" which should
be cast back to a "B" explicitly. This is corrct behavior as not all
"A"s can be of kind "B".

One way to get the kind of behaviour you are looking for is to have the
caller infer the type from the function and also have the function
templated to work with any type that inherits from A. I have shown this
in the following example with the extra step of not explicitly
instantiating the template as that can also be inferred:

module temp;

import std.stdio;

class A
{
void foo()
{
writefln("A.foo()");
}
}

class B : A
{
override void foo()
{
writefln("B.foo()");
}
void bar()
{
writefln("B.bar()");
}
}

T func(T : A)(T a)
{
//.. do stuff ..
return a;
}

void main()
{
auto thing = func(new B()); //same as auto thing = func!(B)(new B());
thing.foo();
thing.bar();

}


I'm not completly sure of how const/invariant work with object
references so I won't attempt to answer that.

I think you missed my point.
I used an example with classes as a generalization.
remember that in D we have:
        const(T)
          /\
         /  \
        /    \
       T    invariant(T)

basically I want to do:

ref const(T) max(T)(ref const(T) a, ref const(T) b){ return (a>b)?a:b; }

int a = 4;
int b = 5;
int res = max(a, b); //works due to "downcasting" from const(int) to int

this can be limited to constancy only if it doesn't make sense for classes.

Reply via email to