Question

Quelle est la différence entre

(type)value

et

type(value)

en C ++?

Était-ce utile?

La solution

Il n'y a pas de différence. selon la norme (& # 167; 5.2.3):

Un spécificateur de type simple (7.1.5) suivi d'une liste d'expressions entre parenthèses construit une valeur du type spécifié à partir de la liste d'expressions. Si la liste d'expressions est une expression unique, l'expression de conversion de type est équivalente (de manière définie et si sa signification est définie) à l'expression de conversion correspondante (5.4).

La question spécifiant la différence entre type (valeur) et (type) valeur , il n'y a absolument aucune différence.

Si et seulement si vous traitez avec une liste de valeurs séparée par des virgules, il peut y avoir une différence. Dans ce cas:

Si la liste d'expressions spécifie plus d'une valeur, le type doit être une classe avec un constructeur correctement déclaré (8.5, 12.1) et l'expression T (x1, x2, ...) est équivalente à la déclaration T t (x1, x2, ...); pour certains, la variable temporaire inventée t, avec pour résultat la valeur de t en tant que valeur.

Comme Troubadour l’a souligné, il existe certains noms de types pour lesquels la version type (valeur) ne sera tout simplement pas compilée. Par exemple:

char *a = (char *)string;

compilera, mais:

char *a = char *(string);

ne sera pas. Le même type avec un nom différent (créé avec un typedef , par exemple) peut fonctionner si:

typedef char *char_ptr;

char *a = char_ptr(string);

Autres conseils

Il n'y a pas de différence. la norme C ++ (éditions 1998 et 2003) est claire sur ce point. Essayez le programme suivant, assurez-vous d’utiliser un compilateur conforme, tel que la prévisualisation gratuite disponible à l'adresse 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;
}

Remarque: unsigned (a_var) est différent, mais montre d'une manière que ces jetons exacts peuvent signifier autre chose. Il déclare une variable nommée a_var de type unsigned et n'est pas du tout un cast. (Si vous connaissez les pointeurs sur des fonctions ou des tableaux, considérez comment vous devez utiliser un parenthèse autour de p dans un type tel que void (* pf) () ou < code> int (* pa) [42] .)

(Des avertissements sont produits car ces déclarations n'utilisent pas la valeur et dans un programme réel qui serait presque certainement une erreur, mais tout fonctionne toujours. Je n'avais tout simplement pas le cœur de le changer après avoir tout mis en ligne up.)

Il n'y a pas de différence lorsque les deux sont des castes, mais parfois 'type (valeur)' n'est pas un cast.

Voici un exemple tiré du projet de norme N3242, section 8.2.1:

struct S 
{
    S(int);
};

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

Dans ce cas, 'int (a)' n'est pas un cast car 'a' n'est pas une valeur, c'est un nom de paramètre entouré de parenthèses redondantes. Le document indique

  

L'ambiguïté résultant de la similitude entre un style de fonction   casting et une déclaration mentionnée en 6.8 peuvent également se produire dans le contexte   d'une déclaration. Dans ce contexte, le choix est entre une fonction   déclaration avec un ensemble redondant de parenthèses autour d'un paramètre   nom et une déclaration d'objet avec une distribution de style fonction comme   initialiseur. Comme pour les ambiguïtés mentionnées en 6.8, le   La solution consiste à envisager toute construction susceptible de constituer un   déclaration une déclaration.

En c, il n'y a pas de type (valeur) , alors que dans c / c ++, les deux type (valeur) et (type) valeur sont autorisé.

Pour illustrer vos options en C ++ (un seul contrôle de sécurité)

#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
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top