Extend the call site default argument expansion mechanism?
Simen Kjærås
simen.kjaras at gmail.com
Wed May 16 09:01:29 UTC 2018
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
More information about the Digitalmars-d
mailing list