Appelant la fonction pointeur à membre en appel à une fonction passée à une fonction de modèle
-
13-09-2019 - |
Question
Ceci est le modèle de fonction à condition que je suis en train d'utiliser:
template <class Process, class BTNode>
void postorder(Process f, BTNode* node_ptr)
{
if (node_ptr != 0)
{
postorder( f, node_ptr->left() );
postorder( f, node_ptr->right() );
f( node_ptr->data() );
}
}
Ceci est mon appel, et la fonction que je suis de passage:
void city_db::print_bst() {
postorder(&city_db::print, head);
}
void city_db::print(city_record target)
{
std::cout << target.get_code();
}
Ceci est le temps de compilation (G ++) erreur que je reçois:
CityDb.cpp: 85: instancié de ici
BinTree.template: 80: Erreur: doit utiliser ou « . » '-> pour appeler fonction pointeur à membre dans « f (...) »
make: *** [CityDb.o] Erreur 1
Ceci est en référence à la f( node_ptr->data() );
de ligne dans le modèle de fonction.
Ceci est un projet Structures de données. La cession a été modifiée de sorte que nous ne avons pas besoin de passer d'une fonction à une fonction, mais je me suis intéressé à ce depuis un certain temps, et je me sens comme je l'ai presque ici. Je suis épuisé Google et Lab assistanats, donc si StackOverflow a des idées, ils seraient grandement appréciés.
La solution
Votre problème est que postorder accepte un objet de fonction qui doit être appelée ainsi:
f(arg);
Vous passez un pointeur à la fonction de membre. Vous devez d'abord appeler mem_fun pour faire un objet fonction du pointeur vers un membre:
std::mem_fun(&city_db::print)
Le but de la fonction de retour prend deux arguments: le pointeur vers un city_db (implicite ce pointeur), et l'objet à imprimer. Vous pouvez lier le premier à cela avec bind1st, comme ceci:
std::bind1st(std::mem_fun(&city_db::print), this)
Et maintenant, vous devriez être en mesure d'appeler postorder sur elle:
postorder(std::bind1st(std::mem_fun(&city_db::print), this), head);
Autres conseils
Vous avez besoin d'une instance de city_db
appeler print
sur.
Qu'est-ce que vous passez est un pointeur vers une fonction membre (penser comme une fente dans le vtable), mais vous avez besoin d'un pointeur this
aussi. Vous pouvez passer cela dans un autre argument à la fonction postorder
.
template <class Object, class Process, class BTNode>
void postorder(Object* obj, Process f, BTNode* node_ptr)
{
if (node_ptr != 0)
{
postorder(obj, f, node_ptr->left() );
postorder(obj, f, node_ptr->right() );
((obj)->*(f))( node_ptr->data() );
}
}
Voir C ++ FAQ Lite
Vous devez soit faire city_db :: print () statique ou fournir un objet _db ville.
Comme écrit
void city_db::print(city_record target)
{
std::cout << target.get_code();
}
ne dépend pas de l'état de la classe. Déclarer en fonction statique et compilateur n'a pas besoin pointeur this
pour l'appeler.
FAQ sur le sujet.