Thread overview
Problems using 'with' statement
Jan 04, 2014
Adam S
Jan 04, 2014
bearophile
Jan 04, 2014
Adam S
Jan 04, 2014
bearophile
January 04, 2014
I've encountered an issue using the 'with' statement. Can anyone explain why the following requires that I explicitly specify the variable name, even though it is within a 'with'?

class Foo {
    auto test(alias val)() if (is(typeof(val) == int)){}
    auto test(alias val)() if (!is(typeof(val) == int)){}
}

void main() {

    auto bar = new Foo;

    with (bar) {
        //test!2();        //fails to compile
        //test!"cats"();   //fails to compile
        bar.test!2();      //works
        bar.test!"cats"(); //works
    }
}

The commented out lines fail with:
    Error: need 'this' for 'test' of type 'pure nothrow @safe void()'

Thanks
January 04, 2014
Adam S:

> I've encountered an issue using the 'with' statement. Can anyone explain why the following requires that I explicitly specify the variable name,

Perhaps because "test" is not a member variable name. It's a (templated) class method.

Bye,
bearophile
January 04, 2014
On Saturday, 4 January 2014 at 20:56:41 UTC, Adam S wrote:
>
> I've encountered an issue using the 'with' statement. Can anyone explain why the following requires that I explicitly specify the variable name, even though it is within a 'with'?
>
> class Foo {
>     auto test(alias val)() if (is(typeof(val) == int)){}
>     auto test(alias val)() if (!is(typeof(val) == int)){}
> }
>
> void main() {
>
>     auto bar = new Foo;
>
>     with (bar) {
>         //test!2();        //fails to compile
>         //test!"cats"();   //fails to compile
>         bar.test!2();      //works
>         bar.test!"cats"(); //works
>     }
> }
>
> The commented out lines fail with:
>     Error: need 'this' for 'test' of type 'pure nothrow @safe void()'
>
> Thanks

Most template member funs seems to work fine. The issue only seems to appear when the member function is overloaded. For example

class Foo {
    auto test(alias val)() if (is(typeof(val) == int)){}
    //auto test(alias val)() if (!is(typeof(val) == int)){}

}

void main() {
    auto bar = new Foo;

    with (bar) {
        test!2();      //works
    }
}

works fine until the overload of test is uncommented. Then the same error occurs.
January 04, 2014
Adam S:

> Most template member funs seems to work fine. The issue only seems to appear when the member function is overloaded. For example
>
> class Foo {
>     auto test(alias val)() if (is(typeof(val) == int)){}
>     //auto test(alias val)() if (!is(typeof(val) == int)){}
>
> }
>
> void main() {
>     auto bar = new Foo;
>
>     with (bar) {
>         test!2();      //works
>     }
> }
>
> works fine until the overload of test is uncommented. Then the same error occurs.

with() was designed and created to access fields of structs in a simpler way. In D also enum and class members are usable with with(). Your use case seems a corner case of a usage pattern that was not included. So perhaps you have to write an enhancement request.

Bye,
bearophile