【发布时间】:2011-07-13 02:43:21
【问题描述】:
左值是绑定到确定的内存区域的值,而右值是一个表达式值,它的存在是暂时的,不一定指向确定的内存区域。每当在需要右值的位置使用左值时,编译器都会执行左值到右值的转换,然后继续求值。
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
表示使用实际参数A(5) 调用函数ret_a 调用转换构造函数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&) 和 @987654344 时,编译器应该无法推断出最佳匹配函数@ 在重载函数候选集中。
此外,问题(我之前问过的)是:
给定对象如何同时匹配右值引用和左值引用?
【问题讨论】:
-
“左值”和“右值”指的是表达式,而不是对象。
-
谢谢。我想问题是如何将 a 对象绑定到右值和左值引用?另外:“int n = 3; n 是一个引用 int 对象的表达式。表达式 n 是一个左值。” eetimes.com/discussion/programming-pointers/4023341/… 如果这是正确的,那么
a对象(上图)在初始化时不会被视为本身的表达式吗?
标签: c++ reference rvalue-reference rvalue lvalue