2012-02-08 6 views
6

Il seguente C++ non sono validi perché le variabili di riferimento richiedono initializers:Inizializzazione delle variabili di riferimento con l'operatore condizionale

int& a; // illegal 
if (isfive) { 
    a = 5; 
} else { 
    a = 4; 
} 

Tuttavia, MSVC sembra pensare questo è bene:

int& a = isfive ? 5 : 4; 

Ciò implica per me che MSVC tratta effettivamente l'operatore condizionale come una singola espressione e non lo espande in un'istruzione if-else.

È sempre valido C++ per inizializzare un riferimento utilizzando l'operatore condizionale?

+0

Sono curioso di sapere cosa succede se provi a confrontarlo a livello di assieme ... – beta0x64

+3

Come puoi confrontare su un codice di livello assemblato che compila e codice che non lo fa? –

+0

Cosa fa? Per favore, posta l'assemblea! :-) – Florian

risposta

5

MSVC ha un'estensione "non standard". Ciò significa che consente il codice non funzionante. C'è una buona ragione per cui è proibito.

Si noti inoltre che

int& a = 5; 

non è legale in standard C++ sia.

In generale, tuttavia, è legale inizializzare un riferimento const con qualsiasi espressione che può essere convertita nel tipo corretto (compreso l'uso dell'operatore condizionale). Ed è legale inizializzare un riferimento non const con un lvalue del tipo corretto, che l'operatore condizionale produce in determinate condizioni.

+1

Beh, cosa sai, a questa domanda ho risolto un problema che non sapevo nemmeno di avere. Grazie! – Kai

0

È operatore, parte dell'espressione, non un'istruzione. E non puoi lasciare il riferimento non inizializzato anche per poco tempo ;-)

3

L'operatore condizionale è un'espressione, non un'istruzione. È perfettamente corretto inizializzare un riferimento come quello. È un po 'come inizializzare un riferimento chiamando una funzione.

Nota che il tuo riferimento deve essere const se lo si lega ai provvisori (una regola che MSVC++ ignora stupidamente).

+0

* È perfettamente corretto inizializzare un riferimento come quello * solo se ignoriamo il fatto che non è possibile associare un riferimento non const a un valore rvalue ... (cioè 'const int & r = isfive? 4: 5;' sta bene , ma 'int & r = isfive? 4: 5;' non lo è) –

+0

@ DavidRodríguez-dribeas sì, ho aggiunto una nota a riguardo qualche tempo fa. –

2

Il codice che hai postato non compilare con VC++ 2010:

Errore 1 Errore C2440: 'inizializzazione': impossibile convertire da 'int' a 'int &'

Cambiare la linea a:

const int& a = isfive ? 5 : 4; 

lo rende compilato.

+0

Suppongo che stiate usando l'opzione '/ Za' (disabilita le estensioni della lingua)? –

+0

@BenVoigt: No. Sembra che il problema sia risolto: http://technet.microsoft.com/en-us/query/szywdw8k –

+0

Mi chiedo cosa stia facendo su TechNet invece che su MSDN. Ci sono ancora alcuni bug correlati, ma contento di vedere risolto il caso più tipico. –

1

non è OK

int& a = isfive ? 5 : 4; 

a meno che non si dichiara il riferimento "a" come const.

4

L'operatore ternario non si espande in un costrutto if-else (non in base alla lingua, l'implementazione potrebbe generare binari equivalenti, ma a livello di lingua sono diversi). Così il seguente codice è valido:

int four = 4, five = 5; 
int& r = condition? four : five; 

L'esempio originale nella questione dipende da un'estensione di Microsoft che (erroneamente) permette vincolante un riferimento non const a un'espressione rvalue.

Problemi correlati