2009-10-30 29 views

Respuesta

50

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 tipos es equivalente (en definición, y si se define en el significado) a la expresión de conversión correspondiente (5.4).

Dado que la pregunta especifica la diferencia entre type(value) y (type)value, no hay absolutamente ninguna diferencia.

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

Si la lista de expresiones especifica más de un único 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 alguna variable temporal inventada t, con el resultado siendo el valor de t como valor r.

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

char *a = (char *)string; 

compilará, pero:

char *a = char *(string); 

no lo hará. El mismo tipo con un nombre diferente (por ejemplo, creado con un typedef) puede trabajar sin embargo:

typedef char *char_ptr; 

char *a = char_ptr(string); 
+0

Solo para tipos incorporados. – Troubadour

+7

Um, no, no hay diferencia. +1 –

+2

Bueno, tal vez :) Pero, ¿qué pasa con los tipos de puntero no tipificados? – Troubadour

13

No hay diferencia; el estándar de C++ (ediciones de 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 sí muestra una forma de esas fichas exactas pueden significar otra cosa. Está declarando una variable llamada a_var de tipo sin signo, y no es un molde en absoluto. (Si está familiarizado con punteros a funciones o matrices, considerar cómo se tiene que utilizar un parens alrededor p en un tipo como void (*pf)() o int (*pa)[42].)

(advertencias se producen ya que estas declaraciones no utilizan el valor y en un programa real que casi seguro sería un error, pero todo sigue funcionando. Simplemente no tuve valor para cambiarlo después de alinear todo).

+0

¿Buen formato de código, fue ese el pretendido? – squelart

+2

@squelart: No al principio, pero una vez que se acercó lo trabajé, y simplemente no tuve el valor de cambiarlo para deshacerme de las advertencias. –

6

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

He aquí un ejemplo de proyecto de norma 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 un yeso porque 'a' no es un valor, es un parámetro nombre rodeado de paréntesis redundantes. El documento afirma

La ambigüedad que surge de la similitud entre una conversión de estilo de función 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 declaración de función con un conjunto redundante de paréntesis alrededor de un nombre de parámetro 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, la resolución es considerar cualquier construcción que podría ser una declaración como una declaración.

1

En c no hay type (value), mientras que en c/C++ tanto type (value) y (type) value se admiten.

0

para ilustrar sus opciones en C++ (sólo uno tiene un control 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 
} 
Cuestiones relacionadas