Переменные, объявленные &&

Размышляя о (x | r | l | pr | gl) значениях, следующий вопрос пришел мне на ум:

Рассмотрим следующие две объявления переменных:

X x = ...;

и

X&& x = ...;

и предположим, что ... не доставляют xvalue.

Может ли кто-нибудь подумать о том, что код не использует decltype, в котором это имеет значение? В обоих случаях (x) будет на lvalue типа X, не так ли?

Ответ 1

Шаблоны без аргументов не могут ссылаться на временные. Таким образом, учитывая

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

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

template<X&> class woof {};

имеем

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

Если ... не ограничивается значением класса X, то нарезка является менее неясным способом сделать два неэквивалентных. Дано:

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

Y meow() { return {}; }

Тогда:

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

Таким образом:

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

Ответ 2

Может быть, искусственный пример, но с

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

X makeX() {return {};}

после компиляции

X&& x = makeX();

тогда как ниже

X x = makeX();