classe modèle intérieur modèle de classe dans c ++
-
11-09-2019 - |
Question
Noob ici encore à expérimenter avec des modèles. Essayer d'écrire un traitement de messages modèle de classe
template <typename T> class MessageProcessor {
//constructor, destructor defined
//Code using t_ and other functions
foo( void ) {
//More code in a perfectly fine method
}
private: T *t_
};
Tous défini dans un fichier d'en-tête. Je l'ai construit et testé ma classe et tout va bien. Maintenant, je suis en train de faire ceci:
template <typename T> class MessageProcesor {
//Same stuff as before
foo(void) {
//Same code as before in foo, but one new line:
t_->getMessageSender<MessageType>();
}
private: T *t_;
};
Cependant, cette ligne me donne une erreur de mauvaise expression de type avant jeton « > ».
J'ai ajouté les fichiers d'en-tête nécessaires pour définir ce qu'est un MessageType est. Je l'ai utilisé cette fonction beaucoup de temps avant, mais pas dans ce contexte.
Je pense que le compilateur n'aime pas le fait que la fonction de modèle est entièrement défini (spécialisé?) Dans un modèle de classe non définie (non spécialisée?). Je grokking pas complètement ce qui fait un modèle « spécialisé ». La plupart des explications centrent sur les notions de « complet » ou « partielle », mais pas ce qui en fait spécialisé en premier lieu.
Toutes mes excuses si vous voulez voir plus de code. Je n'ai pas accès à Internet au travail et c'est là que je fais cela, je dois donc tout mettre dans mon mental « scratchpad » et ramener à la maison.
La solution
Votre fonction membre « foo » a besoin d'un type de retour et vous avez besoin d'utiliser le mot-clé « modèle » lorsque vous utilisez des modèles membres dans les expressions dépendantes (expressions dont la signification se prévaloir directement ou indirectement sur un paramètre de modèle générique)
t_->template getMessageSender<MessageType>(); // ok
t_->getMessageSender<MessageType>(); // not ok
Peut-être cet exemple vous aidera à apprécier lorsqu'un modèle de membre a besoin à préfixé par le mot-clé « modèle » [Note: dans l'intérêt de symétrie, vous pouvez toujours utiliser le préfixe « modèle » sur membre modèles, mais il est facultatif lorsqu'il est utilisé sur une expression non dépendante.
struct MyType
{
template<class T> void foo() { }
};
template<class U>
struct S
{
template<class T>
void bar()
{
MyType mt; // non-dependent on any template parameter
mt.template foo<int>(); // ok
mt.foo<int>(); // also ok
// 't' is dependent on template parameter T
T t;
t.template foo<int>(); // ok
t.foo<int>(); // not ok
S<T> st; // 'st' is dependent on template parameter T
st.template foo<int>(); // ok
st.foo<int>(); // not ok
S<MyType> s; // non-dependent on any template parameter
s.bar<int>(); // ok
s.template bar<int>(); // also ok
}
};
L'espoir qui aide.
Autres conseils
Ajoutez le mot-clé entre template
->
et le nom de la méthode du modèle:
t_->template getMessageSender<MessageType>();
Probablement, MessageType On ne sait pas à ce moment-là. Il vous manque un include, une résolution d'espace de nom ou d'une déclaration?
si THT est pas, comment est-getMessageSender
déclaré, et comment est-MessageType
?
En général, en C ++, il est pas un problème si T ne sait pas à ce moment-là (bien ... il est compliqué, mais quand même).
En outre, le message d'erreur contient généralement le type pour lequel il est jugé à insantiated. Essayez d'afficher le message d'erreur complet au moins.
Avez-vous d'autres appels semblables à des méthodes telles que getMessageSender qui sont sans canevas?
t_->getMessageSender<MessageType>();
Il est juste le type de retour de votre fonction qui manque. L'élément de t_
est entièrement défini.
Une spécialisation d'un modèle est une version « spéciale » votre outil pour les arguments de modèle spécifique. Un exemple:. std::vector
est la version spécialisée du générique std::vector
Une spécialisation partielle est une implémentation de votre code générique où tous les arguments de modèle sont fournis.
Cela fonctionne bien sur le compilateur Visual Studio 2010.
class One
{
public:
void newFoo() ;
template < class T > void foo()
{
T obj ; // obj is dependent on template parameter
obj.newFoo() ; // and this works
}
}
Il suffit de garder la réponse mise à jour !!!