JohnB
JohnB

Reputation: 13713

Variables declared by &&

Thinking about (x|r|l|pr|gl)values, the following question came to my mind:

Consider the following two variable declarations:

X x = ...;

and

X&& x = ...;

and assume the ... do not deliver an xvalue.

Can anybody think of code not using decltype in which this makes a difference? In both cases, (x) will by an lvalue of type X, won't it?

Upvotes: 12

Views: 555

Answers (2)

T.C.
T.C.

Reputation: 137310

Template non-type arguments cannot refer to a temporary. Thus, given

struct X {};
X purr() { return {}; }

X x1 = purr();
X&& x2 = purr();

template<X&> class woof {};

we have

woof<x1> w1; // OK
woof<x2> w2; // Error

If ... isn't limited to a prvalue of type X, then slicing is a less obscure way to make the two non-equivalent. Given:

struct X { virtual ~X() = default; };
struct Y : X {};

Y meow() { return {}; }

Then:

X x1 = meow();        // slices
X&& x2 = meow();      // doesn't slice

Thus:

dynamic_cast<Y&>(x1); // throws std::bad_cast
dynamic_cast<Y&>(x2); // OK

Upvotes: 5

Jarod42
Jarod42

Reputation: 217145

Maybe artificial example, but with

struct X
{
    X() = default;
    X(const X&) = delete;
    X operator =(const X&) = delete;
    X(X&&) = delete;
    X operator =(X&&) = delete;
};

X makeX() {return {};}

following compiles

X&& x = makeX();

whereas following doesn't

X x = makeX();

Upvotes: 7

Related Questions