Déclaration / définition de modèle explicite dans VS 2012

Le code suivant déclare un modèle, une définition d’instanciation explicite, puis une déclaration d’instanciation explicite:

template  T Double(T number) { return number * 2; } extern template int Double(int); // declaration template int Double(int t); // definition int main(int argc, char* argv[]) { int n = Double(10); return 0; } 

donne une erreur:

 error C2929: 'int Double(int)' : explicit instantiation; cannot explicitly force and suppress instantiation of template-class member 

dans Visual Studio 2012.

J’ai l’impression, à http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1987.htm, que cela devrait être valide, car la définition suit la déclaration.

Est-ce que je manque quelque chose?

Votre programme est bien formé. Le paragraphe 14.7.2 / 11 de la norme C ++ 11 précise:

Si une entité fait l’object d’une déclaration d’instanciation explicite et d’une définition d’instanciation explicite dans la même unité de traduction, la définition doit suivre la déclaration. […]

Votre programme respecte cette contrainte et n’enfreint aucune autre règle. Par conséquent, ceci est qualifié de bogue dans VC11.

Il semble que ce problème ait été signalé à Microsoft Connect 620017 :

Publié par Microsoft le 03/12/2010 à 13h52

Bonjour,

Comme vous l’avez noté, notre implémentation de modèles externes n’est pas conforme à la norme C ++-0x. Nous avons toujours notre ancienne implémentation d’extension. Bien que nous ne disposions pas des ressources nécessaires pour implémenter la version C ++ – 0x de cette fonctionnalité dans la prochaine version de Visual Studio, les problèmes de conformité sont une priorité pour nous. Nous avons actuellement l’intention d’implémenter cette fonctionnalité dans une future version de Visual Studio.

Merci d’avoir pris le temps de signaler ce problème. Nous l’apprécions.

Jamie Eckman Visual C ++ Team

C’était à partir de 2010, donc par “prochaine version”, il voulait dire VS2012.

Ce bogue de conformité Visual C ++ est traité dans Visual Studio 2013, disponible ici . Ce correctif permet de placer des déclarations de extern template dans des fichiers d’en-tête afin de supprimer l’instanciation de modèles tout en déclarant une instanciation explicite dans un module, ce qui peut réduire le temps de compilation et le gonflement du code. L’annulation des instructions (c’est-à-dire une demande d’instanciation explicite, suivie d’une déclaration de extern template avec les mêmes arguments de modèle) provoque toujours l’erreur C2929, car il semble que vous tentiez maintenant de supprimer quelque chose que vous avez déjà explicitement instancié.