Thread overview
BUG: opApply dg(inout...) and template classes
Nov 11, 2005
Garett Bass
Nov 12, 2005
Carlos Santander
Nov 13, 2005
Thomas Kuehne
November 11, 2005
I get a compiler error under v.0.138 when I try to cast a template object to its parent interface when passing it to the delegate argument of opApply.  The workaround forces me to store the cast to a temporary variable, then pass the temporary to the opApply delegate.

------------
private import std.stdio;

interface Foo {
    void foo();
}

class GenericFoo(T) : Foo {
    T* value;
    void foo() {
        writefln("GenericFoo!(%s).foo()", (typeid(T)).toString());
    }
}

class FooArray {
    GenericFoo!(int) gf;

    this() { gf = new GenericFoo!(int); }

    int opApply(int delegate(inout Foo) dg){
        int result = 0;
        for (int i = 0; i < 5; i++) {
            gf.value = &i;
            //result = dg(gf); // Error: cast(Foo)(gf) not an lvalue
            //result = dg(cast(Foo)gf);   // Error: ditto
            //result = dg((cast(Foo)gf)); // Error: ditto
            Foo f = cast(Foo)gf; // Workaround
            result = dg(f);      // Ok
            if (result) break;
        }
        return result;
    }
}

int main(char[][] args) {
    FooArray fa = new FooArray;
    foreach (Foo f; fa) f.foo();
    return 0;
}

------------

I suspect this test case may be generalized further, but I'm not sure how to go about simplifying it.  Any help would be appreciated.

Regards,
Garett


November 12, 2005
Garett Bass escribió:
> I get a compiler error under v.0.138 when I try to cast a template object to its parent interface when passing it to the delegate argument of opApply.  The workaround forces me to store the cast to a temporary variable, then pass the temporary to the opApply delegate.
> 
> ------------
<snip>
> ------------
> 
> I suspect this test case may be generalized further, but I'm not sure how to go about simplifying it.  Any help would be appreciated.
> 
> Regards,
> Garett 
> 
> 

Here's a reduced version:

void foo(inout int i) {}

void main()
{
        long l;
        foo(l); //6
}

With gdc 0.16, I get: "foo.d:6: cast(int)(l) is not an lvalue". There've been times when allowing this has beed asked, but in the end, I think it's somewhat understandable behavior.

-- 
Carlos Santander Bernal
November 13, 2005
Garett Bass schrieb am 2005-11-11:
> I get a compiler error under v.0.138 when I try to cast a template object to its parent interface when passing it to the delegate argument of opApply.  The workaround forces me to store the cast to a temporary variable, then pass the temporary to the opApply delegate.
>
> ------------
> private import std.stdio;
>
> interface Foo {
>     void foo();
> }
>
> class GenericFoo(T) : Foo {
>     T* value;
>     void foo() {
>         writefln("GenericFoo!(%s).foo()", (typeid(T)).toString());
>     }
> }
>
> class FooArray {
>     GenericFoo!(int) gf;
>
>     this() { gf = new GenericFoo!(int); }
>
>     int opApply(int delegate(inout Foo) dg){
>         int result = 0;
>         for (int i = 0; i < 5; i++) {
>             gf.value = &i;
>             //result = dg(gf); // Error: cast(Foo)(gf) not an lvalue
>             //result = dg(cast(Foo)gf);   // Error: ditto
>             //result = dg((cast(Foo)gf)); // Error: ditto
>             Foo f = cast(Foo)gf; // Workaround
>             result = dg(f);      // Ok
>             if (result) break;
>         }
>         return result;
>     }
> }
>
> int main(char[][] args) {
>     FooArray fa = new FooArray;
>     foreach (Foo f; fa) f.foo();
>     return 0;
> }
>
> ------------
>
> I suspect this test case may be generalized further, but I'm not sure how to go about simplifying it.  Any help would be appreciated.

Added to DStress as http://dstress.kuehne.cn/nocompile/i/inout_01.d

Thomas