www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - auto ref and arrays

reply "Jack Applegame" <japplegame gmail.com> writes:
I don't understand why auto ref doesn't work with arrays.

void test1(T)(auto ref const T[] val) {}
void test2(T)(auto ref const T val) {}
void main() {
   int b;
   test2(b); // OK
   string a;
   test1(a); // Error: cast(const(char[]))a is not an lvalue
}

Since a is mutable itself, compiler uses ref storage class.
cast(const(char[]))a isn't an lvalue, so it's impossible to pass 
it by ref.

But cast(const int)b isn't an lvalue too. Why it's no errors in 
this case?
Nov 27 2012
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 11/27/2012 02:09 PM, Jack Applegame wrote:
 I don't understand why auto ref doesn't work with arrays.

 void test1(T)(auto ref const T[] val) {}
 void test2(T)(auto ref const T val) {}
 void main() {
 int b;
 test2(b); // OK
 string a;
 test1(a); // Error: cast(const(char[]))a is not an lvalue
 }

 Since a is mutable itself, compiler uses ref storage class.
 cast(const(char[]))a isn't an lvalue, so it's impossible to pass it by ref.

 But cast(const int)b isn't an lvalue too. Why it's no errors in this case?

Sorry, I am not answering the question but is 'auto ref' is legal as a parameter? It is not documented. On the other hand, 'auto ref' is a legal return type. Ali
Nov 27 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, November 27, 2012 14:44:51 Ali Çehreli wrote:
 On 11/27/2012 02:09 PM, Jack Applegame wrote:
 I don't understand why auto ref doesn't work with arrays.
 
 void test1(T)(auto ref const T[] val) {}
 void test2(T)(auto ref const T val) {}
 void main() {
 int b;
 test2(b); // OK
 string a;
 test1(a); // Error: cast(const(char[]))a is not an lvalue
 }
 
 Since a is mutable itself, compiler uses ref storage class.
 cast(const(char[]))a isn't an lvalue, so it's impossible to pass it by
 ref.
 
 But cast(const int)b isn't an lvalue too. Why it's no errors in this case?

Sorry, I am not answering the question but is 'auto ref' is legal as a parameter? It is not documented. On the other hand, 'auto ref' is a legal return type.

Yes, it's legal on function paramters - but only on templated functions. It was an attempt at solving the const& problem. It's supposed to take both lvalues and rvalues but not copy lvalues. I think that there's a decent chance that TDPL talks about it, but I'm not sure, though if it does, what it describes isn't quite what auto ref does at the moment, since the original idea for auto ref would have worked with non-templated functions, but Andrei and Walter miscommunicated on its intent, and it wasn't implemented that way (and would actually be problematic to implement that way). As for the OP's question, I'd say that it looks like a bug. My guess is that a cast is being inserted as part of the auto ref implementation, and a cast does _not_ result in an lvalue, so that's why it would fail. I don't know why it thinks it needs a cast though. - Jonathan M Davis
Nov 27 2012
prev sibling next sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 11/27/12 23:44, Ali Çehreli wrote:
 On 11/27/2012 02:09 PM, Jack Applegame wrote:
 I don't understand why auto ref doesn't work with arrays.

 void test1(T)(auto ref const T[] val) {}
 void test2(T)(auto ref const T val) {}
 void main() {
 int b;
 test2(b); // OK
 string a;
 test1(a); // Error: cast(const(char[]))a is not an lvalue
 }

 Since a is mutable itself, compiler uses ref storage class.
 cast(const(char[]))a isn't an lvalue, so it's impossible to pass it by ref.

 But cast(const int)b isn't an lvalue too. Why it's no errors in this case?

Sorry, I am not answering the question but is 'auto ref' is legal as a parameter? It is not documented.

It's legal and documented: http://dlang.org/template.html Whether the argument is mutable or not shouldn't matter -- compiler bug; both examples should compile (limiting auto-ref to only modifiable lvalues wouldn't make sense). artur
Nov 27 2012
prev sibling next sibling parent "Jack Applegame" <japplegame gmail.com> writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9090
Nov 27 2012
prev sibling parent "Dan" <dbdavidson yahoo.com> writes:
On Tuesday, 27 November 2012 at 22:09:21 UTC, Jack Applegame 
wrote:
 I don't understand why auto ref doesn't work with arrays.

 void test1(T)(auto ref const T[] val) {}
 void test2(T)(auto ref const T val) {}
 void main() {
   int b;
   test2(b); // OK
   string a;
   test1(a); // Error: cast(const(char[]))a is not an lvalue
 }

 Since a is mutable itself, compiler uses ref storage class.
 cast(const(char[]))a isn't an lvalue, so it's impossible to 
 pass it by ref.

 But cast(const int)b isn't an lvalue too. Why it's no errors in 
 this case?

I thought with auto ref you dispense with the const since it figures it out. The below seems to work. Thanks, Dan import std.traits; import std.stdio; void test1(T)(auto ref T val) if(!isArray!T) { writeln("Nonarray ", typeid(typeof(val))); } void test1(T)(auto ref T val) if(isArray!T) { writeln("Array ", typeid(typeof(val))); } void main() { string a; const(string) b = "string that never changes"; test1(a); test1(b); int[] x; test1(x); int y; test1(y); }
Nov 28 2012