Question

Existe-t-il une bonne raison pour qu'un ensemble vide de parenthèses (parenthèses) ne soit pas valide pour appeler le constructeur par défaut en C ++?

MyObject  object;  // ok - default ctor
MyObject  object(blah); // ok

MyObject  object();  // error

Il semble que je tape "" () " automatiquement à chaque fois. Y a-t-il une bonne raison pour que cela ne soit pas autorisé?

Était-ce utile?

La solution

La plupart des analyses vexantes

Ceci est lié à ce que l’on appelle "l'analyse la plus frustrante de C ++". Fondamentalement, tout ce qui peut être interprété par le compilateur comme une déclaration de fonction sera interprété comme une déclaration de fonction.

Une autre instance du même problème:

std::ifstream ifs("file.txt");
std::vector<T> v(std::istream_iterator<T>(ifs), std::istream_iterator<T>());

v est interprété comme une déclaration de fonction avec 2 paramètres.

La solution consiste à ajouter une autre paire de parenthèses:

std::vector<T> v((std::istream_iterator<T>(ifs)), std::istream_iterator<T>());

Ou, si vous disposez de C ++ 11 et de l'initialisation de liste (également appelée initialisation uniforme):

std::vector<T> v{std::istream_iterator<T>{ifs}, std::istream_iterator<T>{}};

Avec cela, il n'y a aucun moyen que cela puisse être interprété comme une déclaration de fonction.

Autres conseils

Parce que c'est le traité comme déclaration d'une fonction:

int MyFunction(); // clearly a function
MyObject object(); // also a function declaration

La même syntaxe est utilisée pour la déclaration de fonction - par exemple. la fonction objet , ne prenant aucun paramètre et renvoyant MyObject

Parce que le compilateur pense qu'il s'agit d'une déclaration d'une fonction qui ne prend aucun argument et renvoie une instance de MyObject.

Je suppose que le compilateur ne saurait pas si cette déclaration:

  

objet MyObject ();

est un appel de constructeur ou un prototype de fonction déclarant une fonction nommée objet avec le type de retour MonObjet et aucun paramètre.

Vous pouvez également utiliser la méthode de construction la plus prolixe:

MyObject object1 = MyObject();
MyObject object2 = MyObject(object1);

En C ++ 0x, cela permet également de auto :

auto object1 = MyObject();
auto object2 = MyObject(object1);

Comme mentionné à plusieurs reprises, il s'agit d'une déclaration. C'est ainsi pour la compatibilité ascendante. Un des nombreux domaines de C ++ qui sont maladroits / incohérents / douloureux / faux en raison de son héritage.

De n4296 [dcl.init]:

  

[Remarque:
Etant donné que () n'est pas autorisé par la syntaxe de initializer ,    X a (); n'est pas la déclaration d'un objet de la classe X, mais le   déclaration d’une fonction ne prenant aucun argument et renvoyant un X. Le   form () est autorisé dans certains autres contextes d’initialisation (5.3.4,   5.2.3, 12.6.2).   
& n ° 8212; note de fin]

Comme l'ont dit les autres, il s'agit d'une déclaration de fonction. Depuis C ++ 11, vous pouvez utiliser l'initialisation d'accolade si vous avez besoin de voir l'élément vide qui indique explicitement qu'un constructeur par défaut est utilisé.

Jedi luke{}; //default constructor
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top