Pregunta

¿Cuál es la diferencia entre

(type)value

y

type(value)

en C ++?

¿Fue útil?

Solución

No hay diferencia; según el estándar (§5.2.3):

Un especificador de tipo simple (7.1.5) seguido de una lista de expresiones entre paréntesis construye un valor del tipo especificado dada la lista de expresiones. Si la lista de expresiones es una sola expresión, la expresión de conversión de tipo es equivalente (en definición y si está definida en significado) a la expresión de conversión correspondiente (5.4).

Como la pregunta especifica la diferencia entre tipo (valor) y (tipo) valor , no hay absolutamente ninguna diferencia.

Si y solo si se trata de una lista de valores separados por comas, puede haber una diferencia. En este caso:

Si la lista de expresiones especifica más de un solo valor, el tipo será una clase con un constructor adecuadamente declarado (8.5, 12.1), y la expresión T (x1, x2, ...) es equivalente en efecto a la declaración T t (x1, x2, ...); para algunas variables temporales inventadas t, cuyo resultado es el valor de t como valor de r.

Como señaló Troubadour, hay ciertos nombres de tipos para los que la versión type (value) simplemente no se compilará. Por ejemplo:

char *a = (char *)string;

se compilará, pero:

char *a = char *(string);

no lo hará. Sin embargo, el mismo tipo con un nombre diferente (por ejemplo, creado con un typedef ) puede funcionar:

typedef char *char_ptr;

char *a = char_ptr(string);

Otros consejos

No hay diferencia; El estándar C ++ (ediciones 1998 y 2003) es claro sobre este punto. Pruebe el siguiente programa, asegúrese de utilizar un compilador que sea compatible, como la vista previa gratuita en http://comeaucomputing.com/ tryitout / .

#include <cstdlib>
#include <string>
int main() {
  int('A'); (int) 'A'; // obvious
  (std::string) "abc"; // not so obvious
  unsigned(a_var) = 3; // see note below
  (long const&) a_var; // const or refs, which T(v) can't do
  return EXIT_SUCCESS;
}

Nota: unsigned (a_var) es diferente, pero muestra una forma en que esos tokens exactos pueden significar otra cosa. Está declarando una variable llamada a_var de tipo unsigned, y no es una conversión en absoluto. (Si está familiarizado con los punteros a funciones o matrices, considere cómo debe usar un parens alrededor de p en un tipo como void (* pf) () o < code> int (* pa) [42] .)

(Las advertencias se producen ya que estas declaraciones no usan el valor y en un programa real que seguramente sería un error, pero todo sigue funcionando. Simplemente no tuve el corazón para cambiarlo después de hacer que todo alineara arriba)

No hay diferencia cuando ambos son lanzamientos, pero a veces 'type (value)' no es un lanzamiento.

Aquí hay un ejemplo del borrador estándar N3242, sección 8.2.1:

struct S 
{
    S(int);
};

void foo(double a) 
{
    S w( int(a) ); // function declaration
    S y( (int)a ); // object declaration
}

En este caso, 'int (a)' no es una conversión porque 'a' no es un valor, es un nombre de parámetro rodeado de paréntesis redundantes. El documento dice

  

La ambigüedad que surge de la similitud entre un estilo de función   emitir y una declaración mencionada en 6.8 también puede ocurrir en el contexto   de una declaración. En ese contexto, la elección es entre una función   declaración con un conjunto redundante de paréntesis alrededor de un parámetro   nombre y una declaración de objeto con un molde de estilo de función como el   inicializador Al igual que para las ambigüedades mencionadas en 6.8, el   la resolución es considerar cualquier construcción que posiblemente pueda ser una   declaración una declaración.

En c no hay type (value) , mientras que en c / c ++ tanto type (value) como (type) value son permitido.

Para ilustrar sus opciones en C ++ (solo una tiene una verificación de seguridad)

#include<boost/numeric/conversion/cast.hpp> 

using std::cout;
using std::endl;
int main(){

    float smallf = 100.1;

    cout << (int)smallf << endl; // outputs 100 // c cast
    cout << int(smallf) << endl; // outputs 100 // c++ constructor = c cast

    cout << static_cast<int>(smallf) << endl; // outputs 100
//  cout << static_cast<int&>(smallf) << endl; // not allowed
    cout << reinterpret_cast<int&>(smallf) << endl; // outputs 1120416563
    cout << boost::numeric_cast<int>(smallf) << endl; // outputs 100

    float bigf = 1.23e12;

    cout << (int)bigf << endl; // outputs -2147483648
    cout << int(bigf) << endl; // outputs -2147483648

    cout << static_cast<int>(bigf) << endl; // outputs -2147483648
//  cout << static_cast<int&>(bigf) << endl; // not allowed
    cout << reinterpret_cast<int&>(bigf) << endl; // outputs 1401893083
    cout << boost::numeric_cast<int>(bigf) << endl; // throws bad numeric conversion
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top