inout template parameter, or a solution to the templated container issue

monarch_dodra monarchdodra at gmail.com
Wed Jun 12 05:29:55 PDT 2013


On Wednesday, 12 June 2013 at 09:16:30 UTC, Timothee Cour wrote:
> Why not use a castConstSafe function that'll transform A!T into 
> A!(const
> T), generically:
>
> auto ref castSafe(T,S)(auto ref S a){...}
> S a; T b=castSafe!T(a); //same as T b=cast(T)(a) except that it 
> only
> compiles if S=>T only involves nonconst=>const conversions 
> (works
> recursively):
> example: A!(double) => A!(const double) is allowed but not 
> other direction.
>
> More specifically:
> auto ref castConstSafe(S)(auto ref S a){...} //transforms A!T 
> into A!(const
> T), generically
>
> then:
> void foo(B a) if (is(ElementType!B == const)){...}
> A!(const double) a1;
> A!(double) a2;
> foo(a1.castConstSafe); //works
> foo(a2.castConstSafe); //works
>
> All it requires is to pass a.castConstSafe instead of a.

Because Foo!T and Foo!(const T) are completely unrelated types. 
Casting from one to the other gives 0 guarantees it actually 
works. For example:

//----
struct Foo(T)
{
     static if (is(T == const int))
     {
         void do_it()const{writeln("this");}
     }
     else
     {
         void do_it()const{writeln("that");}
     }
}

void main()
{
     Foo!int a;
     const(Foo!int)*  pa = &a;
     Foo!(const int)* pb = cast(Foo!(const int)*) &a;
     pa.do_it(); //prints "that"
     pb.do_it(); //prints "this"
}
//----

Of course, I could have also changed the members, making memory 
mapping incompatible, amongst others...


More information about the Digitalmars-d mailing list