55 votes

Est-ce qu'aucune parenthèse sur un constructeur sans argument n'est une norme de langage?

J'ai été la compilation d'un programme C++ dans Cygwin à l'aide de g++ et j'ai eu une classe dont le constructeur a pas d'arguments. J'ai eu l'lignes:

MyClass myObj();
myObj.function1();

Et lorsque j'essaie de compiler, j'ai le message:

erreur: demande d'un membre "fonction1" dans "myObj", ce qui est de la non-type de classe " MyClass ()()'

Après un peu de recherche, j'ai trouvé que la solution était de changer cette première ligne de MyClass myObj;

Je pourrais jurer que j'ai fait constructeur vide déclarations avec des parenthèses en C++ avant. Est-ce probablement une limitation de le compilateur que j'utilise ou ne la norme du langage vraiment dire ne pas utiliser des parenthèses pour un constructeur sans arguments?

63voto

Charles Bailey Points 244082

Bien que MyClass myObj(); puisse être analysé en tant que définition d'objet avec un initialiseur vide ou une déclaration de fonction, la norme de langage spécifie que l'ambiguïté est toujours résolue en faveur de la déclaration de fonction. Un initialiseur de parenthèses vide est autorisé dans d'autres contextes, par exemple dans une expression new ou la construction d'un temporaire initialisé par une valeur .

58voto

Peter Alexander Points 31990

C'est ce qu'on appelle le problème d'analyse le plus contrariant. Quand l'analyseur voit

 MyClass myObj();
 

Il pense que vous déclarez une fonction appelée myObj qui n'a pas de paramètres et renvoie un MyClass .

Pour le contourner, utilisez:

 MyClass myObj;
 

20voto

suszterpatt Points 5172

J'ai trouvé ça dans la norme C++ (§8.5.8):

Un objet dont l'initialiseur est un ensemble vide de parenthèses, c'est à dire, (), doit être la valeur d'initialisation.

[Note: depuis le () n'est pas autorisée par la la syntaxe pour l'initialiseur,

X a ();

n'est pas la déclaration d'un objet de la classe X, mais la déclaration d'une fonction ne prenant aucun argument et renvoyant un X. La forme () est autorisé dans certaines autres initialisation des contextes (5.3.4, 5.2.3, 12.6.2). -la note de fin ]

11voto

Liz Albin Points 1371

Il s'agit d'un problème assez bien connu qui ne dépend pas du compilateur. Essentiellement, ce que vous faisiez était de déclarer une fonction retournant le type MyObj. Sans surprise, vous ne pouviez pas appeler son constructeur. Voir la FAQ C ++ pour une bonne explication

4voto

AProgrammer Points 31212

Pourtant, un autre succès de l'analyse la plus vexante. Voir par exemple http://stackoverflow.com/questions/1300327/sort-function-does-not-work-with-function-object-created-on-stack

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X