Thread overview
static opCall not working?
Jul 19, 2015
TC
Jul 19, 2015
Ali Çehreli
Jul 20, 2015
Marc Schütz
Jul 20, 2015
Dicebot
July 19, 2015
I tested the code from: http://dlang.org/struct.html
Section: Dynamic Initialization of Structs


struct S
{
    int a;

    static S opCall(int v)
    {
        S s;
        s.a = v;
        return s;
    }

    static S opCall(S v)
    {
        S s;
        s.a = v.a + 1;
        return s;
    }
}

S s = 3; // sets s.a to 3
S t = s; // sets t.a to 3, S.opCall(s) is not called

which does not compile (Error: cannot implicitly convert expression (3) of type int to S).

What is wrong here? Docs or behavior? Tested it on asm.dlang.org where it fails with all compiler versions.
July 19, 2015
On 07/19/2015 03:26 AM, TC wrote:
> I tested the code from: http://dlang.org/struct.html
> Section: Dynamic Initialization of Structs
>
>
> struct S
> {
>      int a;
>
>      static S opCall(int v)
>      {
>          S s;
>          s.a = v;
>          return s;
>      }
>
>      static S opCall(S v)
>      {
>          S s;
>          s.a = v.a + 1;
>          return s;
>      }
> }
>
> S s = 3; // sets s.a to 3
> S t = s; // sets t.a to 3, S.opCall(s) is not called
>
> which does not compile (Error: cannot implicitly convert expression (3)
> of type int to S).
>
> What is wrong here? Docs or behavior? Tested it on asm.dlang.org where
> it fails with all compiler versions.

The docs are not clear: s and t are not meant to be module-scope variables, which should be initialized in a 'static this()' (or 'shared static this()'). Put them inside a function like main() and it works fine.

Ali

July 20, 2015
On Sunday, 19 July 2015 at 13:25:41 UTC, Ali Çehreli wrote:
> On 07/19/2015 03:26 AM, TC wrote:
>> I tested the code from: http://dlang.org/struct.html
>> Section: Dynamic Initialization of Structs
>>
>>
>> struct S
>> {
>>      int a;
>>
>>      static S opCall(int v)
>>      {
>>          S s;
>>          s.a = v;
>>          return s;
>>      }
>>
>>      static S opCall(S v)
>>      {
>>          S s;
>>          s.a = v.a + 1;
>>          return s;
>>      }
>> }
>>
>> S s = 3; // sets s.a to 3
>> S t = s; // sets t.a to 3, S.opCall(s) is not called
>>
>> which does not compile (Error: cannot implicitly convert expression (3)
>> of type int to S).
>>
>> What is wrong here? Docs or behavior? Tested it on asm.dlang.org where
>> it fails with all compiler versions.
>
> The docs are not clear: s and t are not meant to be module-scope variables, which should be initialized in a 'static this()' (or 'shared static this()'). Put them inside a function like main() and it works fine.

I think that's not what the OP means. The documentation is indeed saying that a struct with static opCall() can be used to _construct_ the structure, with exactly this syntax, i.e. not with `S a = S(3);`, but with `S a = 3;`. I, too, find this very surprising. opCall() is not a constructor...
July 20, 2015
On Sunday, 19 July 2015 at 10:26:04 UTC, TC wrote:
> What is wrong here? Docs or behavior? Tested it on asm.dlang.org where it fails with all compiler versions.

Docs are wrong here. `static opCall` was never intended to be used as constructor and I consider it a bad style in general. This is simply a workaround that people unhappy with lack of default struct constructor used but language actively resists such misusage (`auto s = new S(42)` won't work too btw) and it only causes confusion.