2012-02-08 6 views
6

La siguiente C++ no es válida porque las variables de referencia requieren inicializadores:Inicialización de variables de referencia con el operador condicional

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

Sin embargo, MSVC parece pensar que esto está bien:

int& a = isfive ? 5 : 4; 

Esto implica para mí que MSVC en realidad trata al operador condicional como una sola expresión y no lo expande en una instrucción if-else.

¿Siempre es válido C++ inicializar una referencia usando el operador condicional?

+0

Tengo curiosidad por saber qué sucede si intentas compararlo en un nivel de ensamblaje ... – beta0x64

+3

¿Cómo se puede comparar con un código de nivel ensamblado que compila y código que no lo hace? –

+0

¿Qué hace? Por favor, publique el montaje! :-) – Florian

Respuesta

5

MSVC tiene una "extensión" no estándar. Lo que significa es que permite código roto. Hay una buena razón por la que esto está prohibido.

Nótese también que

int& a = 5; 

no es legal en C++ estándar tampoco.

En general, sin embargo, es legal inicializar una referencia const con cualquier expresión que se pueda convertir al tipo correcto (incluido el uso del operador condicional). Y es legal inicializar una referencia que no sea const con un valor l del tipo correcto, que el operador condicional cede bajo ciertas condiciones.

+1

Bueno, ¿qué sabes, hacer esta pregunta resolvió un problema que ni siquiera sabía que tenía. ¡Gracias! – Kai

0

Es operador, parte de la expresión, no una declaración. Y no puede dejar la referencia sin inicializar ni siquiera por un momento ;-)

3

El operador condicional es una expresión, no una declaración. Está perfectamente bien inicializar una referencia como esa. Es un poco como inicializar una referencia llamando a una función.

Tenga en cuenta que su referencia debe ser const si la vincula a los temporales (una regla que MSVC++ ignora estúpidamente).

+0

* Está perfectamente bien inicializar una referencia como esa * solo si ignoramos el hecho de que no puede enlazar una referencia no constante a un valor r ... (es decir, 'const int & r = isfive? 4: 5;' está bien , pero 'int & r = isfive? 4: 5;' no es) –

+0

@ DavidRodríguez-dribeas Sí, agregué una nota sobre eso hace un tiempo. –

2

El código que envió no se compila con VC++ 2010:

de error 1 error C2440: 'inicialización': no ​​se puede convertir de 'int' a 'int &'

Cambio de la línea a:

const int& a = isfive ? 5 : 4; 

lo hace compilar.

+0

Supongo que está utilizando la opción '/ Za' (deshabilitar extensiones de idioma)? –

+0

@BenVoigt: No. Parece que el problema está solucionado: http://technet.microsoft.com/en-us/query/szywdw8k –

+0

Me pregunto qué está haciendo eso en TechNet en lugar de MSDN. Todavía hay algunos errores relacionados, pero me alegro de ver que el caso más típico es fijo. –

1

No es buena

int& a = isfive ? 5 : 4; 

menos que se declare la referencia "a" como const.

4

El operador ternario no se expande a un constructo if-else (no según el idioma, la implementación podría generar binarios equivalentes, pero en el nivel del idioma son diferentes). Por lo que el siguiente código es válido:

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

El ejemplo original en la cuestión depende de una extensión de Microsoft que (incorrectamente) permite unir una referencia no const a una expresión rvalue.

Cuestiones relacionadas