Compiler error with slices, .dup and ref Parameter

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Nov 20 01:20:34 PST 2014


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. :)



More information about the Digitalmars-d-learn mailing list