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