i am currently implementing a binary tree in c++ and i want to traverse it with a function called in_order().
is there any way to pass a function as an argument, so that i can do things like below (without having to write the code to traverse the list more than once)?
struct tree_node; // and so on
class tree; // and so on
void print_node () {
// some stuff here
}
// some other functions
tree mytree();
// insert some nodes
mytree.in_order(print_node);
mytree.in_order(push_node_to_stack);
mytree.in_order(something_else);
Yes, you can do this in a number of ways. Here are two common possibilities.
Old-style function pointers
class mytree
{
// typedef for a function pointer to act
typedef void (*node_fn_ptr)(tree_node&);
void in_order(node_fn_ptr)
{
tree_node* pNode;
while (/* ... */)
{
// traverse...
// ... lots of code
// found node!
(*fnptr)(*pNode);
// equivalently: fnptr(*pNode)
}
}
};
void MyFunc(tree_node& tn)
{
// ...
}
void sample(mytree& tree)
{
// called with a default constructed function:
tree.inorder(&MyFunc);
// equivalently: tree.inorder(MyFunc);
}
Using functors
With a template member, works with function pointers
class mytree
{
// typedef for a function pointer to act
typedef void (*node_fn_ptr)(tree_node&);
template<class F>
void in_order(F f)
{
tree_node* pNode;
while (/* ... */)
{
// traverse...
// ... lots of code
// found node!
f(*pNode);
}
}
};
struct ExampleFunctor
{
void operator()(tree_node& node)
{
// do something with node
}
}
void sample(mytree& tree)
{
// called with a default constructed function:
tree.inorder(ExampleFunctor());
}
Yes, you can use a function pointer as a parameter to in_order
. You may also need to overload it, in case the passed functions' signatures don't match. For functions like print_node
, declare in_order like this (provided its return type is void
as well):
void tree::in_order( void (*)() )
{
//implementation
}
I think you should use the visitor pattern instead.
http://en.wikipedia.org/wiki/Visitor_pattern
The base visitor class should have a virtual method to operate on a node. Pass the visitor as an argument to your in_order method. Then derive your visitor as many times as you want for any operation you want to do.
来源:https://stackoverflow.com/questions/1673329/c-pass-function-as-parameter-to-another-function