Sulla base di @Answer songyuanyao, ho notato che il mio errore Stavo controllando la cosa sbagliata: la mia intenzione era di verificare se il risultato di i+j
fosse associare a un riferimento di rvalue, ma ho controllato se esso è un riferimento di rvalue.
decltype deduce il tipo basato sulla value category, non si basa su ciò che reference type il valore sarebbe legano a:
1) se la categoria del valore di espressione è xvalue
, allora decltype rendimenti T&&
;
2) se la categoria di valore di espressione è lvalue
, quindi decltype produce T&
;
3) se la categoria di valore di espressione è prvalue
, quindi decltype produce T
.
Come mostrato nella lista, dal C++ 11, rvalues
non esistono come categoria distinta sul livello più basso. Ora sono una categoria composita che contiene sia prvalues
sia xvalues
. La domanda come scritta chiede se l'espressione è un rvalue reference
e controlla se si tratta di un xvalue
.
Dalla lista sopra, è chiaro che i+j
è un prvalue
, quindi si applica il terzo caso. Questo spiega perché decltype(i + j)
è int
e non int&&
. Entrambi xvalues
e prvalues
si legano a riferimenti di rvalue.
Così controllando se i+j
si lega ad un lvalue reference
o un rvalue reference
conferma che, in effetti, lega a un rvalue reference
:
void foo(const int& f)
{
std::cout << "binds to lvalue reference" << std::endl;
}
void foo(int&& f)
{
std::cout << "binds to rvalue reference" << std::endl;
}
void test(int i, int j)
{
foo(i); // lvalue -> lvalue ref
foo(std::move(i)); // xvalue -> rvalue ref
// (std::move converts the argument to a rvalue reference and returns it as an xvalue)
foo(i + j); // prvalue -> rvalue ref
}
In conclusione:i+j
è non un riferimento rvalue , ma si lega a uno.
È solo semplice vecchi dati. Non penso che tu possa std :: move an int .. – 0xbaadf00d
Questo è sempre stato int, da tempo immemorabile (a.k.a. primo Unix). Come ti muoveresti '2 + 2'? – bipll
Puoi molto 'std :: move' an' int' e, oltre al punto, l'OP sta chiedendo la categoria di valore di' i + j'. –