2017-10-16 23 views
1

je le code suivant dans le fichier d'en-tête:modèle syntaxe <> requis par Solaris CC, mais interdite par MSVC et GCC

template<typename A, typename B> class TemplateTest; 

template<> 
class TemplateTest<int, double> 
{ 
public: 
    float operator() (float a); 
}; 

La définition dans le fichier cpp:

template<> // this is problematic line 
float TemplateTest<int, double>::operator()(float a) 
{ 
    float b; 
    b = a + 5; 
    return b; 
} 

avec le "template <>" dans la définition, MSVC renvoie l'erreur C2910 car il interprète operator() comme une méthode template au lieu d'une méthode d'une classe template. GCC se comporte de manière similaire. Mais Solaris CC requiert le "template <>" (sinon il émet une erreur "" template <> "la syntaxe est requise pour la spécialisation explicite d'un membre de ..."

Donc ma question est de savoir laquelle est correcte et comment rendre le code compile sur toutes ces plates-formes

+0

assurez-vous de lire ceci: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – bolov

+0

@bolov Ce conseil ne s'applique qu'aux définitions avoir au moins un paramètre de modèle. Cette définition spécialisée 'operator()' n'en a aucune. – aschepler

Répondre

0

Vous n'avez pas besoin

template<> // this is problematic line 

exemple complet.

template<typename A, typename B> class TemplateTest; 

template<> 
class TemplateTest<int, double> 
{ 
public: 
    float operator() (float a); 
}; 

float TemplateTest<int, double>::operator()(float a) 
{ 
    return 0; 
} 

Wandbox

Rechercher des "membres des spécialisations" dans C++ Reference

2

CC Solaris est incorrect. Le template<> n'est pas autorisé. C++ 14 Standard [temp.expl.spec]/5:

membres d'un modèle de classe explicitement spécialisés sont définis de la même manière que les membres des classes normales, et ne pas utiliser la syntaxe template<>. ...

[Exemple:

template<class T> struct A { 
    struct B { }; 
    template<class U> struct C { }; 
}; 

template<> struct A<int> { 
    void f(int); 
}; 

void h() { 
    A<int> a; 
    a.f(16); // A<int>::f must be defined somewhere 
} 

// template<> not used for a member of an 
// explicitly specialized class template 
void A<int>::f(int) { /*...*/ } 

... - exemple fin]

Il ressemble à soutenir Solaris CC, vous devrez utiliser quelque chose comme:

#ifdef __SUNPRO_CC 
template <> 
#endif 
float TemplateTest<int, double>::operator()(float a) 
{ 
    float b; 
    b = a + 5; 
    return b; 
} 

Si vous en avez beaucoup, vous pouvez vouloir mettre ce passe-partout dans une macro personnalisée.