On Tuesday, 15 May 2018 at 15:02:36 UTC, jmh530 wrote:
On Tuesday, 15 May 2018 at 14:52:46 UTC, Steven Schveighoffer wrote:
[snip]

It seems opDispatch isn't being used in the with statement. That seems like a bug, or maybe a limitation. I'm not sure how "with" works, but I assumed it would try calling as a member, and then if it doesn't work, try the call normally. Probably it's checking to see if it has that member first.

Annoying...

-Steve

Looks like with statements ignore opDispatch.

struct Foo(int x)
{
    auto opDispatch(string s)()
        if (s == "bar")
    {
        return x++;
    }
}


void main()
{
    int y = 0;
    with(Foo!1)
    {
        y = bar; //error: undefined identifier bar
    }
    assert(y == 2);
}

You've got bugs in your code: ++x has to fail for the template case, since you're trying to increment a compile-time value. This is what the call to bar is lowered to:

    Foo!1.opDispatch!"bar"()

When you try and compile that, you get these error messages:

Error: cannot modify constant 1
Error: template instance `foo.Foo!1.Foo.opDispatch!"bar"` error instantiating

In addition, the with-statement in your code refers to the type Foo!1, not an instance of it. Fixed code:

    struct Foo(int x)
    {
        int n = x;
        auto opDispatch(string s)()
            if (s == "bar")
        {
            n++;
            return n;
        }
    }


    unittest
    {
        int y = 0;
        with(Foo!1())
        {
            y = bar; // Works!
        }
        assert(y == 2);
    }

--
  Simen

Reply via email to