www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - ref barfs template parameter deduction?

reply NaN <divide by.zero> writes:
Ok given the following code...

auto foo(T)(T x)
{
     struct V1 { T* what; }
     V1 v;
     return v;
}

auto bam(T)(T x)
{
     struct V2 { T* what; }
     V2 v;
     return v;
}

void bar()
{
     bam(foo(1));
}


if you change the declaration of foo or bam to "ref T x", ie..

auto foo(T)(ref T x)
auto bam(T)(ref T x)

then the compiler complains thus...


<source>(23): Error: template `test.foo` cannot deduce function 
from argument types `!()(int)`, candidates are:

<source>(7):        `test.foo(T)(ref T x)`

Compiler returned: 1

Why would ref make any difference to deciding what function to 
use, it even says there's only one candidate?

Cheers
May 08 2020
next sibling parent NaN <divide by.zero> writes:
On Friday, 8 May 2020 at 22:03:47 UTC, NaN wrote:
 Ok given the following code...

 auto foo(T)(T x)
 {
     struct V1 { T* what; }
     V1 v;
     return v;
 }

 auto bam(T)(T x)
 {
     struct V2 { T* what; }
     V2 v;
     return v;
 }

 void bar()
 {
     bam(foo(1));
 }
Should have said that compiles fine when x is passed by value.
May 08 2020
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Friday, 8 May 2020 at 22:03:47 UTC, NaN wrote:
 void bar()
 {
     bam(foo(1));
 }


 if you change the declaration of foo or bam to "ref T x", ie..

 auto foo(T)(ref T x)
 auto bam(T)(ref T x)

 then the compiler complains thus...


 <source>(23): Error: template `test.foo` cannot deduce function 
 from argument types `!()(int)`, candidates are:

 <source>(7):        `test.foo(T)(ref T x)`

 Compiler returned: 1

 Why would ref make any difference to deciding what function to 
 use, it even says there's only one candidate?

 Cheers
The integer literal `1` is an rvalue, and can't be passed by reference. If you explicitly instantiate the templates foo and bar in the function call, you get a more informative error message: bam!int(foo!int(1)); Error: function onlineapp.foo!int.foo(ref int x) is not callable using argument types (int) cannot pass rvalue argument 1 of type int to parameter ref int x
May 08 2020
parent NaN <divide by.zero> writes:
On Friday, 8 May 2020 at 22:11:57 UTC, Paul Backus wrote:
 On Friday, 8 May 2020 at 22:03:47 UTC, NaN wrote:

 The integer literal `1` is an rvalue, and can't be passed by 
 reference.

 If you explicitly instantiate the templates foo and bar in the 
 function call, you get a more informative error message:

     bam!int(foo!int(1));

 Error: function onlineapp.foo!int.foo(ref int x) is not 
 callable using argument types (int)
        cannot pass rvalue argument 1 of type int to parameter 
 ref int x
Ooops facepalm! Thanks :)
May 08 2020