我创建了一个非常简单的Tree
实现,我希望能够将一个函数对象传递给我的traverse()
函数。 e.g。
template<class T>
class MyTree
{
public:
void traverse(MyFunction f) {
traverse(root, f);
}
private:
MyTreeNode<T>* root;
void traverse(MyTreeNode<T>*, MyFunction f);
};
问题是,如果我想传递一些参数以及相关节点,我如何声明f
? (指向其他structs
的指针)。或者,任何人都可以指向我一些教程的方向吗?
答案 0 :(得分:2)
一种可能性是使用boost::function
并定义一个仅将您的节点作为参数的函数类型。然后,只要绑定其他参数,就可以从任何函数创建boost::function
对象。
template<class T>
class MyTree
{
public:
typedef boost::function< void (MyTreeNode<T>*) > MyFunction;
void traverse(MyFunction f) {
traverse(root, f);
}
private:
MyTreeNode<T>* root;
void traverse(MyTreeNode<T>*, MyFunction f);
};
tree.traverse( boost::bind( &func_with_args, _1, arg1, arg2 ) );
答案 1 :(得分:2)
您可以将其设为模板成员函数,
template<class T>
class MyTree
{
public:
template<typename Functor>
void traverse(Functor f) {
traverse(root, f);
}
private:
MyTreeNode<T>* root;
template<typename Functor>
void traverse(MyTreeNode<T>* node, Functor f) {
f(node->value);
// etc...
}
};
在此表单中,将接受任何可以作为f(x)
调用的函数对象。
答案 2 :(得分:1)
在这个阶段你可以做很多事情。
旧式C类型解决方案:您可以传递一个函数指针:
template <typename T>
void MyTree<T>::traverse( void (*function)( MyTreeNode<T>*, int ) );
这将把一个函数指针(自由函数)作为参数,该指针将指向MyTreeNode<T>
对象的指针作为第一个参数,将整数作为第二个参数。您可以typedef
使用函数类型来简化使用:
template <typename T>
class MyTree {
public:
typedef void func( MyTreenode<T>*, int ); // typedef the function type
typedef void (*pfunc)( MyTreenode<T>*, int ); // or the function pointer
void traverse( func* function );
void traverse2( pfunc function );
};
您可以借助模板将任何可调用的 thing 作为参数:
template <typename T>
class MyTree {
public:
template <typename Functor>
void traverse( Functor f );
};
如果你让参数类型保持空闲,那么最简单的方法是 simple ,但是如果你尝试传递一个带有不同参数集的可调用实体的错误消息可能不那么简单解析。在内部,您可以使用f
,就像它是一个函数一样,但外部可以是函数或函数对象,包括std::bind
(c ++ 0x)或boost::bind
的结果
您可以向前迈出一步,并使用traverse
(再次,c ++ 0x)或{{1}在std::function
函数的签名中实际执行您要使用的参数}:
boost::function
这个解决方案的优点是很清楚你将如何使用传入的参数(如在函数指针方法中):你将调用template <typename T>
class MyTree {
public:
void traverse( std::function< void (MyTreeNode<T>*, int )> f );
};
f( x, y )
是x
1}}和MyTreeNode<T>*
是一个整数。同时,您通过y
(c ++ 0x)或std::bind
提供模板化解决方案的通用性,可用于使不同实体适应boost::bind
参数,包括自由函数,函数对象,成员函数......
答案 3 :(得分:1)
如果我理解正确,你就会问起如何宣布仿函数。这是一个小代码,可以给你一个想法。
struct A{
void operator()(int x, double d){} // overloaded operator()
};
int main(){
A a;
a(2, 3.0);
}