1

有人可以向我解释为什么 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 member-variablerv.ct时,临时生命周期不会延长,因为有一个特殊的例外:[class.temporary]p5:“在构造函数的 ctor-initializer (12.6.2) 中临时绑定到引用成员一直持续到构造函数退出。”

4

3 回答 3

7

因为您的会员只是一个参考。在第二种情况下,它引用的对象在局部rv变量的定义完成后已经死了。所以后面的访问cout是未定义的行为。

于 2012-09-01T09:35:05.913 回答
3

您的程序具有未定义的行为,因为您正在访问一个悬空引用。临时向量在它出现的完整表达式的末尾被销毁,但您保留对它的引用。

于 2012-09-01T09:35:53.120 回答
2

在 r 值情况下,您将临时绑定到引用。当您到达最后一个输出语句时,它已经消失了。

于 2012-09-01T09:36:00.433 回答