cannot cast

sclytrack sclytrack at ars.com
Thu May 3 01:24:38 PDT 2012


On 05/03/2012 09:33 AM, Namespace wrote:
> On Wednesday, 2 May 2012 at 22:38:36 UTC, Namespace wrote:
>> Other, shorter example:
>>
>> [code]
>> import std.stdio, std.traits;
>>
>> class A {
>> int val;
>>
>> alias val this;
>>
>> T opCast(T : Object)() {
>> writeln("FOO");
>>
>> return to!(T)(this);
>> }
>> }
>>
>> class B : A {
>>
>> }
>>
>> T to(T : Object, U : Object)(const U obj) {
>> return *(cast(T*) &obj);
>> }
>>
>> T const_cast(T)(const T obj) {
>> return cast(T) obj;
>> }
>>
>> void main () {
>> A a = new B();
>> a.val = 42;
>>
>> writefln("a.val: %d", a.val);
>>
>> B* b = cast(B*) &a;
>> writefln("*b.val: %d", b.val);
>>
>> B b1 = to!(B)(a);
>> writefln("b1.val: %d", b1.val);
>>
>> B b2 = cast(B) a;
>> writefln("b2.val: %d", b2.val);
>>
>> const B b3 = cast(B) a;
>>
>> B b4 = const_cast(b3);
>> }
>> [/code]
>>
>> print:
>>
>> alias_this_impl.d(24): Error: function
>> alias_this_impl.A.opCast!(B).opCast () is
>> not callable using argument types ()
>> alias_this_impl.d(44): Error: template instance
>> alias_this_impl.const_cast!(B) e
>> rror instantiating
>>
>> I'm not very skillful in such "template" stories. Maybe someone can
>> help me?
>
> Solved with
>
> T const_cast(T)(const T obj) {
> return to!(T)(obj);
> }
>
> But i think that there must exist a more nicer way to cast away const,
> isn't there?
>
> To cast away "const" with a simple cast to "T" fails (see my post
> above), because i have no idea, how i can restrict my opCast. So i have
> to convert it again with "to". Do some of you have any ideas how i can
> restrict my opCast, so my const_cast doesn't match it, e.g. with some
> template magic?




Unqual können Sie finden in std.traits.


template Unqual(T)
{
     version (none) // Error: recursive alias declaration @@@BUG1308@@@
     {
              static if (is(T U == const U)) alias Unqual!U Unqual;
         else static if (is(T U == immutable U)) alias Unqual!U Unqual;
         else static if (is(T U == inout U)) alias Unqual!U Unqual;
         else static if (is(T U == shared U)) alias Unqual!U Unqual;
         else alias T Unqual;
     }
     else // workaround
     {
              static if (is(T U == shared(const U))) alias U Unqual;
         else static if (is(T U == const U )) alias U Unqual;
         else static if (is(T U == immutable U )) alias U Unqual;
         else static if (is(T U == inout U )) alias U Unqual;
         else static if (is(T U == shared U )) alias U Unqual;
         else alias T Unqual;
     }
}

unittest
{
     static assert(is(Unqual!(int) == int));
     static assert(is(Unqual!(const int) == int));
     static assert(is(Unqual!(immutable int) == int));
     static assert(is(Unqual!(inout int) == int));
     static assert(is(Unqual!(shared int) == int));
     static assert(is(Unqual!(shared(const int)) == int));
     alias immutable(int[]) ImmIntArr;
     static assert(is(Unqual!(ImmIntArr) == immutable(int)[]));
}



More information about the Digitalmars-d-learn mailing list