#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 ?
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"}
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With