Reputation: 1671
Scott Meyers in this talk at 44:15, says const
Rvalue references are used in c++0x standard library to capture certain overloads which are not supposed to be compilable.
Code snippet to illustrate the above mentioned point would be helpful. Thanks.
Upvotes: 3
Views: 54
Reputation: 56547
One usage that I found useful is to disable temporaries biding to reference members. For example, consider the code below:
struct Foo{};
class X
{
const Foo& _foo;
public:
X(const Foo&&) = delete; // prevents rvalue binding
X(const Foo& foo): _foo(foo){} // lvalue is OK
};
Foo get_Foo()
{
return {};
}
const Foo get_const_Foo()
{
return {};
}
Foo& get_lvalue_Foo()
{
static Foo foo;
return foo;
}
int main()
{
// X x1{get_Foo()}; // does not compile, use of deleted function
// X x2{get_const_Foo()}; // does not compile, use of deleted function
X x3{get_lvalue_Foo()}; // OK
}
You definitely want to disable a rvalue being passed to the constructor of X
, since rvalues do not bind to const references via constructor parameters, so you end up with a dangling reference. Why const Foo&&
and not simply Foo&&
? Because if you use X(Foo&&) = delete;
, then if your get_Foo()
returns const Foo
(which is a bad idea, but nevertheless is seen in actual code), it will bind to X(const Foo&)
instead, and you end up with a dangling reference. However, X(const Foo&&)
in the code above is a better match for a const Foo
rvalue, so we obtain the desired effect of not being able to construct an X
with a rvalue.
You may also ask why not defining X(Foo&)
instead for the lvalue constructor. Then you won't be able to bind const
lvalues. So the best approach is to mark X(const Foo&&) = delete;
. Hope this clarifies it.
Upvotes: 1