有人可以向我解释为什么R值的输出与L值不同吗?
#include <iostream>
#include <vector>
using namespace std;
template<typename Ct>
struct ct_wrapper {
Ct&& ct; // R or L ref
explicit ct_wrapper(Ct&& ct)
: ct(std::forward<Ct>(ct)) { std::cout << this->ct[1];};
};
int main() {
// L-val
vector<int> v{1,2,3};
ct_wrapper<vector<int>&> lv(v);
cout << endl << lv.ct[0] << lv.ct[1] << lv.ct[2] << endl;
// R-val
ct_wrapper<vector<int>&&> rv(vector<int>{1,2,3});
cout << endl << rv.ct[0] << rv.ct[1] << rv.ct[2] << endl;
}
输出(gcc48和clang32相同):
2
123
2
003
回答
在与Johannes Schaub的聊天中,它被埋没了,所以我把它放在这里。
当临时向量初始化r-value-ref成员变量rv.ct
时,临时生命周期不会延长,因为有一个特殊的例外:[class.temporary] p5:“临时绑定到构造函数中的引用成员ctor-initializer(12.6.2)一直存在,直到构造函数退出。“
答案 0 :(得分:7)
因为您的会员只是一个参考。在第二种情况下,它引用的对象在本地rv
变量的定义完成后已经死了。因此,cout
中的后续访问是未定义的行为。
答案 1 :(得分:3)
您的程序有未定义的行为,因为您正在访问悬空引用。临时向量在它出现的完整表达式的末尾被销毁,但你保留对它的引用。
答案 2 :(得分:2)
在r值的情况下,您将临时绑定到引用。当你到达最后一个输出语句时它已经消失了。