c++ - una - Visual Studio no está creando un objeto temporal al encasillar?
que es una instancia en c# (1)
Estoy usando Visual Studio Express 2013 y estoy jugando un poco tratando de aprender cosas diferentes en C ++.
Me encontré con un error interesante en el compilador donde no parece crear un objeto temporal al escribir explícitamente el lanzamiento al mismo tipo que la referencia.
#include <iostream>
using namespace std;
int main()
{
int number; // float number;
number = 2;
const int& plainref_i = number;
const int& recastref_i = (int)number; // this goes wrong if number is int
const float& plainref_f = number;
const float& recastref_f = (float)number; // this goes wrong if number is float
number = 3;
std::cout << plainref_i << "/n";
std::cout << recastref_i << "/n";
std::cout << plainref_f << "/n";
std::cout << recastref_f << "/n";
return 0;
}
Esto, cuando se compila en VS, da como resultado la siguiente salida: 3 3 2 2
Pero compilado con gcc, da como resultado la siguiente salida: 3 2 2 2
Si reemplazo "int number"; con "número flotante"; Me meto en VS: 2 2 3 3
y con gcc: 2 2 3 2
Me pregunto si alguien puede confirmar esto como un error y si alguien sabe de una solución / solución posible.
Dado:
int number;
Los resultados de este elenco deben ser un valor prvero:
const int& recastref_i = (int)number; // this goes wrong if number is int
y dado que está usando referencia const entonces puede vincularse al prvalue y su valor debe estar divorciado de cualquier cambio en el number
pero Visual Studio tiene una extensión que produce un lvalue en lugar de un prvalue , por lo que realmente recibe una referencia lvalue al number
que significa que cualquier cambio en el valor del number
se reflejará al verificar el valor de recastref_i
.
El equipo de Visual Studio recomienda usar el indicador /Zc:rvalueCast
para desactivar este comportamiento (el énfasis es mío ):
Cuando se especifica la opción / Zc: rvalueCast, el compilador identifica correctamente un tipo de referencia rvalue como resultado de una operación de conversión de acuerdo con el estándar C ++ 11. Cuando no se especifica la opción, el comportamiento del compilador es el mismo que en Visual Studio 2012. De forma predeterminada, / Zc: rvalueCast está desactivado. Para la conformidad y para eliminar errores en el uso de moldes, recomendamos que use / Zc: rvalueCast.
a diferencia de /Za
que desactivará todas las extensiones que pueden ser problemáticas en escenarios prácticos.
Del borrador de la sección estándar de C ++ 5.4
Conversión de tipo explícito (notación de lanzamiento), párrafo 1, que dice ( énfasis mío ):
El resultado de la expresión de conversión de expresión (T) es de tipo T. El resultado es un valor de l si T es un tipo de referencia lvalor o una referencia rvalue al tipo de función y un valor x si T es una referencia rvalue al tipo de objeto; de lo contrario, el resultado es un valor prve.