Pregunta

#include <iostream>  
struct Bar
{
    int nb_;
    Bar(int nb) :nb_(nb){}
    ~Bar()
    {
        std::cout << "~Bar" << "\n";
    }
}; 

struct Foo
{    
    template<class T>
    Foo(T&& param) :bar_(std::move(param))
    {
        std::cout << "Foo" << "\n";
    } 
    ~Foo()
    {
        std::cout << "~Foo" << "\n";
    }

    Bar&& bar_;
};

int main()
{       
    { 
        Foo foo(Bar(1));
    }

    std::cin.ignore();
}

//Output:
Foo
~Bar 
~Foo

Is this program is legal C++? Does bar_ will become a dangling reference once the Foo constructor will be finished?

If this is not legal in term of C++ standard, when is it useful to have a rvalue reference as a field ?

¿Fue útil?

Solución

Does bar_ will become a dangling reference once the Foo constructor will be finished?

Not quite. It becomes a dangling reference at the point where the temporary created by Bar(1) is destroyed: at the end of the full-expression Foo foo(Bar(1)).

That also shows a usage example of rvalue reference members, for example forward_as_tuple:

struct woof
{
    using my_tuple = std::tuple<std::vector<int>, std::string>;
    my_tuple m;

    woof(my_tuple x) : m(std::move(x)) {}
};

std::vector<int> v{1,2,3,4,5};
woof w( forward_as_tuple(std::move(v), std::string{"hello world"}) );

forward_as_tuple can store rvalue references (here: in a tuple<vector<int>&&, string&&>), which still can be used by the ctor of woof to move v and the temporary created by std::string{"hello world"}.

Otros consejos

Yes, bar_ will become a dangling reference after the constructor has finished.

It rarely makes sense to store a reference, but some cases exist. I don't think there is any difference between the different types of references. The stored reference references another object and you need to make sure that the object is still valid when the reference is used.

Note that if you write

Bar b( 1 );
Foo foo(std::move(b));

foo will not have moved b, it is just storing a reference to it. b is still valid and can be used. Only if you have a member of Foo which actually moves from the stored reference, b will be moved.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top