On 11/20/2014 12:37 AM, anynomous wrote:

> module a;
>
> void init (ref string[] argv) { }
>
> void main(string[] args) {
>      init(args);           //ok
>      auto y = args[1..$];
>      init(y);                 //ok
>      auto x = args.dup;
>      init(x);              //ok
>      init(args[1..$]);     // Error: function a.init (ref string[]
> argv) is not callable using argument types (string[])
>      init(args.dup);       // Error: function a.init (ref string[] argv)
> is not callable using argument types (string[])
> }

Both of the error cases are trying to pass rvalues as arguments to ref parameters. Not possible in D even for reference to const.

Judging from the name init(), I don't think you need ref anyway.

If you really want to write a function that should take both lvalues and rvalues, then a convenient solution is to use 'auto ref', which is available only to templates. For that reason, you have to stick an empty template parentheses just to make it a template:

void init()(auto ref string[] argv) { }

'auto ref' takes lvalues by reference and rvalues by copy. So, the code will work but then if you make modifications to the parameter and it was an rvalue to begin with, your changes will not be visible outside of the function anyway.

So, it is more natural to use 'auto ref' in cases where you don't want to modify the parameter. Then you use 'auto ref const':

void init()(auto ref const string[] argv) { }

Again though, you probably don't want 'ref' anyway. (?)

> The error messages are strange anyway.

Agreed. In the case of assignment to rvalue, dmd is better:

    a + b = 42;  // Error: a + b is not an lvalue

Ali

P.S. Your question is incredibly timely. I've started writing a new chapter titled "Lvalues and Rvalues" just yesterday. :)

Reply via email to