左值是绑定到内存的确定区域的值,而右值是一个表达式值,其存在是暂时的,不一定指向内存的确定区域。每当在需要右值的位置使用左值时,编译器都会执行左值到右值的转换,然后继续求值。
http://www.eetimes.com/discussion/programming-pointers/4023341/Lvalues-and-Rvalues
每当我们构造一个临时(匿名)类对象或从函数返回一个临时类对象时,虽然该对象是临时的,但它是可寻址的。但是,该对象仍然是有效的右值。这意味着对象是 a) 可寻址右值或 b) 当编译器期望使用左值时,它正在从左值隐式转换为右值。
例如:
class A
{
public:
int x;
A(int a) { x = a; std::cout << "int conversion ctor\n"; }
A(A&) { std::cout << "lvalue copy ctor\n"; }
A(A&&) { std::cout << "rvalue copy ctor\n"; }
};
A ret_a(A a)
{
return a;
}
int main(void)
{
&A(5); // A(5) is an addressable object
A&& rvalue = A(5); // A(5) is also an rvalue
}
我们还知道,函数返回的临时对象(在以下情况下a
)是左值,如下代码段:
int main(void)
{
ret_a(A(5));
}
产生以下输出:
int conversion ctor
lvalue copy ctor
表示ret_a
使用实参A(5)
调用函数调用转换构造函数A::A(int)
,该构造函数构造函数的形式参数a
,值为 5。
当函数完成执行时,它会构造一个临时A
对象,使用a
它作为参数,调用A::A(A&)
. 但是,如果我们A::A(A&)
要从重载构造函数列表中删除,返回的临时对象仍然会匹配右值引用构造函数A::A(A&&)
。
这是我不太理解的:对象如何同时a
匹配右值引用和左值引用?很明显,这A::A(A&)
是比A::A(A&&)
(因此a
必须是左值)更好的匹配。但是,由于不能将右值引用初始化为左值,鉴于形式参数a
是左值,它不应该能够匹配对A::A(A&&)
. 如果编译器正在进行左值到右值的转换,那将是微不足道的。A::A(A&)
事实上,从 'A' 到 'A&' 的转换也是微不足道的,两个函数应该具有相同的隐式转换序列等级,因此,当两者A::A(A&&)
都在重载函数中时,编译器不应该能够推断出最佳匹配函数候选集。
此外,问题(我之前问过的)是:
给定对象如何同时匹配右值引用和左值引用?