类,Rvalues和Rvalue引用
左值是绑定到存储器的确定区域的值,而右值是表达式值,其存在是临时的,并且不一定是指存储器的确定区域。只要在预期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 ctorn"; }
A(A&) { std::cout << "lvalue copy ctorn"; }
A(A&&) { std::cout << "rvalue copy ctorn"; }
};
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
)是lvalues作为这个代码段:
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&)
,则返回的临时对象仍将匹配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&&)
都在重载函数候选集中时,编译器不应该推导出最佳匹配函数。
而且,我之前提出的问题是:
给定对象如何匹配右值引用和左值引用?
没有找到相关结果
已邀请:
1 个回复
赐黄
产量:
(即右值,而不是左值)。这是编译器中的错误。然而,这是可以理解的,因为这种行为的规则仅在几个月前(2010年11月)发生了变化。更多关于此的信息。 当函数完成执行时, 然后构建一个临时的
使用
作为其参数的对象 调用
。 其实没有。当函数
完成执行时,它会使用
作为参数构造一个临时的
对象,该对象调用
。这是由于[class.copy] / p33] 1: 当一个省的标准 复制操作已满足或将被满足 除了源的事实 object是一个函数参数,和 指定要复制的对象 通过左值,重载决议来 选择副本的构造函数是 首先表现就像对象一样 由右值指定。如果过载 分辨率失败,或者类型如何 所选的第一个参数 构造函数不是右值引用 到对象的类型(可能 cv-qualified),重载分辨率是 再考虑一下 对象作为左值。 [注意:这个 必须进行两级重载分辨率 无论是否复制都执行 将会出现这种情况。它决定了 如果省略则调用构造函数 未执行,并且已选中 即使构造函数必须是可访问的 电话被忽略了。 - 结束说明] 但是,如果删除
构造函数,则将选择
作为返回。虽然在这种情况下,然后参数
的构造将失败,因为您无法使用rvalue构造它。无论如何忽略这一点,我相信你的最终问题是: 给定对象如何匹配两者 右值参考和左值 参考? 在提到声明时:
答案在草案标准的上述段落中:首先尝试重载决策,好像
是一个右值。如果失败,则使用
作为左值再次尝试重载决策。仅在允许复制省略的情况下(例如返回声明)尝试这两个阶段的过程。 最近刚更改了C ++ 0x草案,以便在返回按值传递的参数时允许两阶段重载解析过程(如示例所示)。这就是我们所看到的不同编译器行为的变化的原因。