Le problème ici est que le compilateur interprète
test(_b);
Pas comme le code qui crée un objet temporaire de type test
passage en paramètre _b
mais comme une déclaration de variable pour une variable nommée _b
de type test
en utilisant le constructeur par défaut. Par conséquent, ce qui ressemble à un morceau de code qui crée un objet temporaire de type test
en utilisant le second constructeur est au contraire en train de créer récursivement un nouvel objet de type test
et en invoquant le constructeur une autre fois.
Pour résoudre ce problème, vous pouvez donner à la variable un nom explicite, comme
test t(_b);
Ceci ne peut être interprété que comme une variable de type test
nommé t
initialisé à l'aide du deuxième constructeur.
J'ai jamais J'ai déjà vu cela, et je programme en C++ depuis des années. Merci de m'avoir montré encore une fois le coin de la langue !
Pour une explication officielle : Selon la spécification ISO C++03, §6.8 :
Il existe une ambiguïté dans la grammaire impliquant les déclarations d'expression et les déclarations : Un énoncé d'expression avec une conversion de type explicite de style fonction (5.2.3) comme sous-expression la plus à gauche peut être indiscernable d'une déclaration où le premier déclarateur commence par un (. Dans ces cas, la déclaration est une déclaration.
(C'est moi qui souligne). En d'autres termes, chaque fois que le C++ pourrait interpréter une déclaration comme une expression (le cast temporaire d'objet) ou comme une déclaration (d'une variable), il choisira la déclaration. La spécification C++ donne explicitement
T(a) ;
En tant qu'exemple de déclaration, et non pas de moulage de a
à quelque chose de type T
.
C'est le C++ Parse la plus vexante - ce qui ressemble à une expression est plutôt interprété comme une déclaration. J'ai déjà vu le MVP, mais je ne l'ai jamais vu dans ce contexte.
J'espère que cela vous aidera !