2015-12-27 16 views
11

Myśląc o wartości (x | r | l | | pr GL), następujące pytanie przyszło mi do głowy:Zmienne zadeklarowane przez &&

Rozważmy następujące dwie deklaracje zmiennych:

X x = ...; 

i

X&& x = ...; 

i zakładamy ... zrobić nie wydania xvalue.

Czy ktoś może pomyśleć o kodzie nie przy użyciu decltype, w którym to robi różnicę? W obu przypadkach, (x) będzie o l-wartości typu X, prawda?

+1

Znaczy różnica w użyciu zmiennych tak zadeklarowane. – JohnB

Odpowiedz

4

argumenty szablonu typu non-cannot refer to a temporary. Tak więc, biorąc pod uwagę

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

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

template<X&> class woof {}; 

mamy

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

Jeśli ... nie jest ograniczony do prvalue typu X, następnie cięcie jest mniej niejasny sposób, aby dwa nierównoważne. Biorąc pod uwagę:

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

Y meow() { return {}; } 

Następnie:

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

Zatem:

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

To bardzo miłe. Dziękuję Ci. – JohnB

6

Może sztuczny przykład, ale z

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

X makeX() {return {};} 

następujące kompiluje

X&& x = makeX(); 

natomiast po nie

X x = makeX(); 
+0

"const" odniesienie też by działało, jeśli nie masz nic przeciwko stałości. –

+0

Dziękuję za odpowiedź i komentarze. Nie wiedziałem o tym, więc nauczyłem się czegoś. Moje pytanie skierowało jednak więcej kodu na tę zmienną. – JohnB

+1

Komentarz: To trochę dziwne. Wydaje się sugerować, że 'x' jest czymś, z czym powinieneś się przenieść, ale twój przykład działa przez sam fakt, że * nie możesz * przenosić' X's. – JohnB