Calling pointer-to-member function in call for a function passed to a template function
This is the prov开发者_StackOverflow社区ided function template I'm trying to use:
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() );
}
}
This is my call, and the function I'm passing:
void city_db::print_bst() {
postorder(&city_db::print, head);
}
void city_db::print(city_record target)
{
std::cout << target.get_code();
}
This is the compile time (G++) error I get:
CityDb.cpp:85: instantiated from here
BinTree.template:80: error: must use ‘.’ or ‘->’ to call pointer-to-member function in ‘f (...)’
make: *** [CityDb.o] Error 1
This is in reference to the line f( node_ptr->data() );
in the function template.
This is for a Data Structures project. The assignment was modified so we don't need to pass a function to a function, but I've been interested in this for quite some time, and I feel like I almost have it here. I've exhausted Google and Lab TA's, so if StackOverflow has ideas, they would be greatly appreciated.
Your problem is that postorder accepts a function object that must be called this way:
f(arg);
You are passing in a pointer to member function. You should first call mem_fun to make a function object from the pointer to member:
std::mem_fun(&city_db::print)
The returned function object takes two arguments: the pointer to a city_db (the implicit this pointer), and the object to be printed. You can bind the first to this with bind1st, like this:
std::bind1st(std::mem_fun(&city_db::print), this)
And now you should be able to call postorder on it:
postorder(std::bind1st(std::mem_fun(&city_db::print), this), head);
You need an instance of city_db
to call print
on.
What you're passing is a pointer to a member function (think of it as a slot in the vtable), but you need a this
pointer too. You could pass this in as another argument to the postorder
function.
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() );
}
}
See C++ FAQ Lite
You need to either make city_db::print() static or provide a city _db object.
As written
void city_db::print(city_record target)
{
std::cout << target.get_code();
}
Does not depend on the class state. Declare it as a static function and compiler will not need this
pointer to call it.
FAQ on the topic.
精彩评论