左值是绑定到存储器的确定区域的值,而右值是表达式值,其存在是临时的,并且不一定是指存储器的确定区域。只要在预期rvalue的位置使用左值,编译器就会执行左值到右值的转换,然后继续进行评估。
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&)
,则返回的临时对象仍将与rvalue-reference构造函数A::A(A&&)
匹配。
这就是我不太了解的内容:对象a
如何匹配右值引用和左值引用?很明显A::A(A&)
比A::A(A&&)
更匹配(因此a
必须是左值)。但是,因为rvalue引用不能初始化为左值,假定形式参数a
是左值,它应该不能匹配对A::A(A&&)
的调用。如果编译器正在进行左值到右值的转换,那将是微不足道的。从'A'转换为'A&amp;'的事实也是微不足道的,两个函数都应该具有相同的隐式转换序列,因此,当A::A(A&)
和A::A(A&&)
都在重载函数候选集中时,编译器不应该推导出最佳匹配函数。
此外,问题(我之前提出的问题)是:
给定对象如何匹配右值引用和左值引用?
答案 0 :(得分:6)
对我来说:
int main(void)
{
ret_a(A(5));
}
收率:
int conversion ctor
rvalue copy ctor
(即rvalue,而不是左值)。这是编译器中的错误。然而,这是可以理解的,因为这种行为的规则仅在几个月前(2010年11月)发生了变化。更多内容如下。
当函数完成执行时, 然后构建一个临时的
A
使用a
作为参数的对象 调用A::A(A&)
。
其实没有。当函数ret_a
完成执行时,它会使用A
作为参数构造一个临时a
对象,该对象将调用A:A(A&&)
。这是由于[class.copy] / p33] 1:
当elision的标准 复制操作已满足或将被满足 除了源的事实 object是一个函数参数,和 指定要复制的对象 通过左值,重载决议来 选择副本的构造函数是 首先表现就像对象一样 由右值指定。如果过载 分辨率失败,或者类型如何 所选的第一个参数 构造函数不是右值引用 到对象的类型(可能 cv-qualified),重载分辨率是 再考虑一下 对象作为左值。 [注意:这个 必须进行两级重载分辨率 无论是否复制都执行 将会出现这种情况。它决定了 如果省略则调用构造函数 未执行,并且已选中 即使构造函数必须是可访问的 电话被忽略了。 - 结束说明]
但是,如果删除A::A(A&&)
构造函数,则会选择A::A(&)
作为返回值。虽然在这种情况下,参数a
的构造将失败,因为您无法使用rvalue构造它。然而,暂时无视这一点,我相信你的最终问题是:
给定对象如何匹配两者 右值参考和左值 参考
参考声明:
return a;
答案在标准草案的上述段落中:首先尝试重载解析,好像a
是一个右值。如果失败,则使用a
作为左值再次尝试重载决策。只有在允许复制省略的情况下(例如返回陈述)才会尝试这两个阶段的过程。
最近更改了C ++ 0x草案,以便在返回按值传递的参数时允许两阶段重载解析过程(如您的示例所示)。这就是我们所看到的不同编译器行为不同的原因。