Comment dois-je faire cette spécialisation explicite?
-
28-09-2019 - |
Question
est possible suivant la conception:
template <typename T>
class Test{
public:
template <typename Z>
void doSomething();
//rest of things
private:
T obj;
//some things
};
Maintenant, s'il était possible que je ferais quelques spécialisations explicites pour doSomething de sorte qu'à la fin je voudrais avoir quelques versions comme ci-dessous:
void doSomething<int>(){
//do something
}
void doSomething<double>(){
//do something
}
...etc
qui semble impossible, je ne peux trouver aucune syntaxe pour faire le travail alors je pensais que la conception devrait être comme suit afin que tous les arguments de modèle doivent être transmis à la classe de modèle lui-même:
template <typename T,typename Z>
class Test{
public:
void doSomething();
//rest of things
private:
T obj;
//some things
};
Alors j'ai essayé une spécialisation partielle qui n'a même pas la compilation:
template <typename T>
void Test<T,int>::doSomething(){
//do something
}
template <typename T>
void Test<T,double>::doSomething(){
//do something
}
...etc
Je suis les erreurs suivantes pour la spécialisation explicite:
erreur # 1: liste des arguments de modèle suivant les paramètres de la liste de nom doit de modèle de classe dans l'ordre utilisé dans la liste des paramètres du modèle
.
erreur # 2: 'Conteneur1':. trop peu d'arguments de modèle
La solution
Afin de se spécialiser explicitement doSomething
vous devez également se spécialiser explicitement Test
.
De 14.7.3 / 18:
Dans une spécialisation explicite déclaration pour un membre d'une classe modèle ou un modèle de membre qui apparaît dans la portée d'espace de noms, le membre matrice et une partie de son enceinte modèles de classe peuvent rester non spécialisé, sauf que le déclaration ne doit pas explicitement spécialiser un modèle de membre de la classe si ses modèles de classe ne sont pas enserrant explicitement spécialisés et .
Autres conseils
Vous ne pouvez pas spécialiser explicitement un modèle de membre à moins que ses modèles de classe enserrant sont également explicitement spécialisés.
Alors que quelque chose comme ceci étant:
template<> template<>
void Test<int>::doSomething<int>()
{
}
vous pouvez toujours faire la ligne de fonction
template <class T>
class Test
{
public:
template <class Z>
void doSomething() { cout << "default" << endl; }
template<>
void doSomething<int>() { cout << "int" << endl;}
template<>
void doSomething<double>() { cout << "double" << endl; }
private:
T obj;
};
Je pense que celui-ci est difficile. Je suppose que vous ne pouvez pas le faire, lisez cette .
Je ne sais pas si cela est un bogue dans g ++, mais cette compile et produit ce que j'attends.
#include<typeinfo>
#include<iostream>
template<typename T>
class Test
{
public:
template<typename Z>
void doSomething();
private:
T obj;
};
template<typename T>
template<typename Z>
void Test<T>::doSomething()
{
Z val;
std::cout << __func__ << ": type " << typeid(val).name() << std::endl;
}
int main(int argc, char *argv[])
{
Test<double> a;
a.doSomething<int>();
a.doSomething<double>();
}
icecrime a posté une réponse temporaire et il sera compilé à cause d'un bug probablement par C ++ 2008 visuelle:
template <typename T>
class Test{
public:
template <typename Z>
void doSomething();
//rest of things
private:
T obj;
//some things
};
template <>
template <typename T>
void Test<T>::doSomething<int>(){
//do something
}
Vérifiez sa réponse actuelle cependant. pas de problème lorsque la compilation spécialisée avec les définitions inline, mais pour les spécialisations des définitions non-inline une fois il y a plus d'une version qu'il ne soit compilé avec succès pas la chose drôle au moins avec VC ++ 2008 est.