Lvalue fades to a value with an automatic error

I apologize if the title of the question is inaccurate - but I am having difficulty understanding what is happening here.

Consider the following class:

struct foo { foo(foo&); }; 

The following are the errors:

 void func(foo& f) { foo bar{f}; } 

However, when I use auto:

 void func(foo& f) { auto bar = foo{f}; } 

I get (gcc):

 test.cpp: In function 'void func(foo&)': test.cpp:6:21: error: no matching function for call to 'foo::foo(foo)' test.cpp:6:21: note: candidate is: test.cpp:2:5: note: foo::foo(foo&) test.cpp:2:5: note: no known conversion for argument 1 from 'foo' to 'foo&' 

(clank)

 test.cpp:6:10: error: no matching constructor for initialization of 'bar' auto bar = foo{f}; ^ ~~~~~~ test.cpp:2:5: note: candidate constructor not viable: expects an l-value for 1st argument foo(foo&); ^ 

Can someone explain why this is a mistake?

Thanks!

Edit: It works if I add a copy constructor to foo. However, I got the impression that declaring a variable + an explicit constructor call on the right side of the "=" syntax is handled specifically and is not a copy, but rather a direct initialization.

+5
source share
2 answers
 auto bar = foo{f}; 

auto is output as foo . Subsequently, your definition is equivalent to

 foo bar = foo{f}; 

You are trying to create an object of type foo that is initialized with a copy using prvalue foo{f} .

The problem is that the copy constructor foo has as its parameter a reference to the lvalue constant, which cannot be bound to rvalue. In addition, the move constructor is implicitly defined because you have a copy constructor declared by the user. Therefore, there is no constructor that can accept foo{f} , and the compiler generates an error message.

+8
source
 auto bar = foo{f}; 

This is copy initialization, and its semantics requires a copy constructor. However, the copy constructor foo accepts a non-const reference, and a non-const reference cannot be tied to a temporary one, that is, foo{f} .

The solution is to create a copy constructor that accepts a const reference, as copy constructors usually do.

+3
source

Source: https://habr.com/ru/post/1209146/


All Articles