Il risultato di un cast è un valore?

Permettere

int a = 0; 

Allora (int)a un valore in C ++ standard?

Diversi compilatori mostrano risultati diversi per questo codice:

 #include  using namespace std; void f(int& x) { cout << "l value" << endl; } void f(int&& x) { cout << "r value" << endl; } int main() { int a = 0; f((int)a); } 

compilatori con risultati diversi:

1) http://cpp.sh/2r6

2) http://webcompiler.cloudapp.net/

Dovrebbe essere un rvalore ma webcompiler è in esecuzione Visual Studio e Visual Studio ha un’estensione che consente agli oggetti temporanei di essere associati a riferimenti non costanti . un bug / estensione che lo induce a generare un lvalue in questo caso, come indicato da Igor sopra, può essere disabilitato usando /Za ( guardalo dal vivo ).

Possiamo vedere che dovrebbe essere un valore rvalue (in particolare un valore nominale ) dalla bozza della sezione standard C ++ 5.4 Conversione di tipo esplicito (notazione cast) paragrafo 1 che dice ( enfasi mia ):

Il risultato dell’espressione cast di espressione (T) è di tipo T. Il risultato è un lvalue se T è un tipo di riferimento di lvalue o un riferimento di rvalue al tipo di funzione e un valore x se T è un riferimento di rvalue al tipo di object; altrimenti il ​​risultato è un valore. [Nota: se T è un tipo non di class che è qualificato in cv, i qualificatori di cv vengono ignorati quando determinano il tipo del valore risultante; vedi 3.10. -End note]

Sia gcc che clang danno come risultato il valore atteso.

Per inciso, consiglierei di usare rextester su webcompiler dato che rextester ti permette di condividere il tuo programma e ha anche la condivisione dal vivo.

Aggiornare

Ben Voigt sottolinea questo bug report e quindi sembra che Visual Studio produca effettivamente un lvalue . Quindi non si tratta semplicemente dell’estensione che consente agli oggetti temporanei di essere associati a riferimenti non costanti .

Come dyp indica che gcc aveva anche un’estensione cast per lvalue .

Aggiornamento 2

Mgetz ha presentato un bug report , la risposta è stata che questo è stato risolto utilizzando il flag / Zc: rvalueCast , la descrizione del flag è la seguente:

Quando viene specificata l’opzione / Zc: rvalueCast, il compilatore identifica correttamente un tipo di riferimento rvalue come risultato di un’operazione di cast in conformità con lo standard C ++ 11. Quando l’opzione non è specificata, il comportamento del compilatore è lo stesso di Visual Studio 2012. Per impostazione predefinita, / Zc: rvalueCast è distriggersto. Per la conformità e per eliminare gli errori nell’uso dei cast, ti consigliamo di utilizzare / Zc: rvalueCast.

Non è chiaro se questo flag sarà abilitato di default nelle versioni future.

Sì, il risultato di un cast su un tipo di object è un valore rval , come specificato da C ++ 11 5.4 / 1:

Il risultato è un lvalue se T è un tipo di riferimento di lvalue o un riferimento di rvalue al tipo di funzione e un valore x se T è un riferimento di rvalue al tipo di object; altrimenti il ​​risultato è un valore .

In Standard C ++ int(a) e (int)a sono rvalue (le altre risposte forniscono riferimenti standard).

Il tuo esempio di codice sta sfruttando un bug / estensione in MSVC, ma non come sembra a prima vista. Come possiamo vedere da questo codice che funziona in MSVC:

 #include  int main() { int x = 0; (int)x = 1; std::cout << x << std::endl; } 

MSVC considera (int)x come un lvalue.

Anche se MSVC ha un'estensione che consente ai rvalues ​​di collegarsi a riferimenti non const; quell'estensione continua a far corrispondere meglio i riferimenti rvalue rispetto ai riferimenti lvalue per rvalue.