Ce problème est basé sur le code qui fonctionne pour moi sur GCC-4.6 mais pas pour un autre utilisateur avec Clang-3.0, à la fois en mode C ++ 0x. Un objet de < Code> MyBase CODE> peut prendre toute liste d'arguments du constructeur, tant que donc si je passe un Le problème de mon utilisateur utilisait ceci en tant que classe de base. Le compilateur s'est plaint que sa classe ne puisse pas synthétiser un constructeur de copie défini automatiquement, car il ne pouvait pas trouver de correspondance avec le modèle de constructeur de la classe de base. N'a-t-il pas appeler t code> prend en charge cette signature de construction. Le problème concerne les fonctions de membre spécial. P>
t code> est constructible par défaut). LI>
mybase code> gagnera un constructeur de copie défini automatiquement (tant que
t code> est copié) qui change
t code> copie -Construction. LI>
mybase
myBase code> Copy-constructeur automatique pour son propre constructeur de copie automatique? Est enraciné par une erreur pour atteindre un conflit? P> p>
3 Réponses :
Je suis juste dans le bar avec Richard Corden et entre nous, nous avons conclu que le problème n'a rien à voir avec des variadiques ou des avales. La construction de copie générée implicitement dans ce cas prend un L'exemple de code que j'ai utilisé pour tester est-ce: p> I nécessaire pour supprimer le Utilisation des listes d'initialistes car ce n'est pas encore pris en charge par Clang. Cet exemple compile à l'exception de l'initialisation de J'ai peut-être mal compris la question mais basée sur Pour souligner que ce problème n'a rien à voir avec des listes d'arguments variadiques ou des r devalues: le code suivant montre le problème que Le constructeur modélisé est appelé, bien qu'il semble que un constructeur de copie soit appelé et que les constructeurs de copies ne sont jamais des modèles. C'est en fait un comportement quelque peu surprenant que j'étais certainement ignorant: p> En conséquence, ajout d'un constructeur variadique comme dans la question à une classe qui n'a pas d'autre Les constructeurs modifient les constructeurs de copie de comportement fonctionnent! Personnellement, je pense que c'est plutôt regrettable. Cela signifie efficacement que la classe Malheureusement, cela ne semble pas fonctionner Avec GCC: il se plaint des constructeurs de copies par défaut (il affirme que le constructeur de copie par défaut prenant une référence non Const ne peut pas être défini dans la définition de la classe). Clang accepte ce code sans plainte. Utilisation d'une définition du constructeur de copie prenant une référence non-Const fonctionne avec GCC et CLANG: P> myBase const & code> comme argument. Le constructeur modélisé déduit le type d'argument comme
myBase & code>. C'est un meilleur match qui s'appelle bien que ce ne soit pas un constructeur de copie.
fv3 code> qui échoue: le constructeur de copie synthétisé pour
myBase
mybase
fv2 code> appelle le constructeur variadidique transférant l'objet à la classe de base. p>
d0 code> et
et
D1 CODE> Il semble que le constructeur par défaut et un constructeur de copie soient synthétisés. Cependant, il s'agit de jolies versions à jour de GCC et de Clang. C'est-à-dire que cela n'explique pas pourquoi aucun constructeur de copie n'est synthétisé car il y a une synthétisée. P>
mybase code> doit également être augmentée avec copie et déplacer des constructeurs également: p>
template <typename T> MyBase<T>::MyBase(MyBase<T>&) = default;
@MOOINGDUCK: Je ne pouvais pas reproduire un problème d'utilisation d'une classe de base correspondante (voir ma mise à jour de la réponse).
Oui, j'ai annoncé des noms différents à l'origine et DUD ne mettez pas à jour tous les endroits. J'espère que j'ai réparé tout maintenant.
J'ai personnellement eu le problème des instantanés de la GCC depuis un certain temps maintenant. J'ai eu du mal à comprendre ce qui se passait (et si cela était autorisé) mais je suis arrivé à une conclusion similaire que Dietmar Kühl: Les constructeurs de copie / déplacement sont toujours ici, mais ne sont pas toujours préférés à travers la mécanique de la surcharge Résolution.
J'utilise cela pour contourner le problème pendant un certain temps maintenant: p> en utilisant avec un constructeur comme le vôtre ressemblerait à: P > template<
typename... Args
, typename = typename enable_if_unrelated<MyBase, Args...>::type
>
MyBase(Args&&... args);
J'ai évoqué la réponse de Dietmar parce que je suis totalement d'accord avec lui. Mais je veux partager une "solution" que j'utilisais quelque temps plus tôt pour éviter ces problèmes:
J'ai intentionnellement ajouté un paramètre factice au constructeur variadique: p> surtout Étant donné que le constructeur accepterait quelque chose sans ce paramètre factice, il semble approprié de rendre le code d'utilisateur explicitement choisir le bon constructeur par (en quelque sorte) "nommer" it. p> Ce n'est peut-être pas possible dans votre cas. Mais parfois, vous pouvez vous en tirer. P> p>
Question interessante. Je recommande de faire un SSCCE (voir sscce.org ) qui fonctionne dans GCC et échoue à Clang pour nous aider à comprendre le problème mieux et le recréer nous-mêmes. De plus, veuillez nous donner le message d'erreur exact de Clang.
En fait, une version de GCC relativement proche de la tête (à partir de 20120202) n'accepte pas également ce code. Il semble que le constructeur de transfert est ramassé même pour la copie. Je ne suis pas tout à fait sûr pourquoi cela. Il n'est pas lié à la "syntaxe d'initialisation uniforme": même lorsque vous utilisez des parenthèses pour la dernière déclaration, il ne compile pas.
Mon code est quelque chose que j'ai écrit une décennie il y a une décennie et mis à jour pour C ++ 11 la semaine dernière. Je ne sais pas comment travailler tout le système TRAC de Boost, mais vous pouvez regarder My changements et le Etat actuel de le fichier (à la révision 77031 à cet écriture).
J'ai trouvé une archive de courrier avec le Description du problème .
Fyi Scott Meyers a discuté de ce problème sur son blog sur Scottmeyers.blogspot. COM / 2012/10 / ...