My search found many posts on rvalue binding to lvalue but not anything similar. Sorry if it is a duplicate.
struct StrHolder {
StrHolder(std::string&& s) : name(s) {}
void Print() const { std::cout << "My name is " << name << std::endl; }
std::string name;
};
int main()
{
StrHolder s{"Tom"}; // (1) - OK, as expected
s.Print();
std::string n1 {"Angi"};
StrHolder p{std::move(n1)}; // (2) - OK, also as expected
p.Print();
//StrHolder q{n1}; // (3) - NOT OK. Also expected. Cannot bind rvalue reference to lvalue
//q.Print();
auto name1 {"Bon"}; // name1 is an lvalue
StrHolder z{name1}; // (4) - Why is this OK ?
z.Print();
return 0;
}
The variable 'name1' declared as auto, above is an lvalue. Therefore, initialization of 'z' should fail but it does not.
Am I missing anything here ?
name1
is an lvalue... but it's not a std::string
, it's a char const*
. Constructing a StrHolder
from it involves making a temporary std::string
using its implicit constructor from char const*
, then invoking StrHolder::StrHolder()
with an rvalue reference to that temporary. name1
gets left alone, and is never moved from.