Question

Can someone explain to me why output for R-value is different from L-value?

#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;
}

Output (same for gcc48 and clang32):

2
123
2
003

Answer

It was buried somewhat in my chat with Johannes Schaub, so I've put it here.

When temporary vector initializes r-value-ref member-variable rv.ct, temporary lifetime is not extended because there's a special exception: [class.temporary]p5: "A temporary bound to a reference member in a constructor's ctor-initializer (12.6.2) persists until the constructor exits."

Was it helpful?

Solution

Because your member is just a reference. In the second case the object it references is already dead after the definition of the local rv variable has finished. So the later access in the cout is undefined behavior.

OTHER TIPS

Your program has undefined behaviour because you are accessing a dangling reference. The temporary vector is destroyed at the end of the full-expression in which it appears, and yet you retain a reference to it.

In the r-value case you bind a temporary to the reference. It will already be gone when you get to the last output statement.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top