erreur C2244 sur la variable de membre modèle avec la fonction d’argument modèle, ne se produit que sur Visual Studio

J’ai rencontré un bogue intéressant, mais extrêmement ennuyant, sur Visual Studio, voici la repro la plus simple: (sans commentaire, la #define permettra à VS de construire le code)

#include  using namespace std; //#define BUILD_ON_VS class CC { public: template struct Foo { template void bar() { cout << "VC likes this!\n"; } #ifndef BUILD_ON_VS template void bar1(); #endif }; Foo m_foo; }; #ifndef BUILD_ON_VS template template void CC::Foo::bar1() { cout << "VC doesn't like this...\n"; } #endif int main() { CC cc; cc.m_foo.bar(); #ifndef BUILD_ON_VS cc.m_foo.bar1(); #endif return 0; } 

Fondamentalement, je ne peux pas placer la définition de la barre de fonctions en dehors de la classe dans Visual Studio. bar et bar1 sont exactement les mêmes sinon. Test sur VS 2010 et VS 2012, les deux ont échoué avec des erreurs:

 error C2244: 'CC::Foo::bar1' : unable to match function definition to an existing declaration definition 'void CC::Foo::bar1(void)' existing declarations 'void CC::Foo::bar1(void 

Cependant, cela fonctionne sur tous les compilateurs en ligne, tels que comstackonline et ideone.

Je veux tout garder dans le fichier cpp, pas dans le .h pour garder la base de code propre.

 Setting var1 to: { template void bar1(); } template template void CC::Foo::bar1() { } 

Cela fonctionne également, mais cela donne au code une apparence idiote en redéfinissant le même paramètre de modèle et beaucoup plus sujet aux bogues. Cela rend également l’interface désordonnée.

Trouvé une solution en tapant au hasard et voir si elle comstack, haha ​​!!! a l’air un peu stupide …

 #include  using namespace std; //#define BUILD_ON_VS class CC { public: template struct Foo; Foo* m_foo; template struct Foo { template void bar(); }; }; template template void CC::Foo::bar() { cout << "VC happen to like this...\n"; } int main() { CC cc; cc.m_foo = new CC::Foo; cc.m_foo->bar<2>(); } 

Je dois créer une classe abstraite et l’instancier avec des arguments de modèle.

Je me demande pourquoi VC ne peut pas le faire automatiquement comme GCC.