借助 C++11,我们获得了 lambda,并且可以在我们真正需要的地方(而不是在它们不真正属于的地方)即时创建函数/函子/闭包。
在 C++98/03 中,创建函数局部函子/闭包的好方法如下:
struct{
void operator()(int& item){ ++item; }
}foo_functor;
some_templated_func(some_args, foo_functor);
遗憾的是,您不能将本地类型用于模板(Visual Studio 允许在启用语言扩展的情况下使用此操作)。我的思路如下:
struct X{
static void functor(int& item){ ++item; }
};
some_templated_func(some_args, &X::functor);
明显的问题是,您无法保存任何状态,因为本地结构/类不能有静态成员。
我解决这个问题的下一个想法是混合使用std::bind1st
and std::mem_fun
以及非静态方法和变量,但不幸的是std::mem_fun
不知何故窒息std::mem_fn(&X::functor)
,这又可能是因为本地结构/类不能在模板中使用:
// wanted, not working solution
struct X{
int n_;
X(int n) : n_(n) {}
void functor(int& item) const { item += n_; }
};
X x(5);
some_templated_func(some_args,std::bind1st(std::mem_fun(&X::functor),&x));
在 VC9 和 VC10 下失败(/Za
,禁用语言扩展)并出现以下错误
error C2893: Failed to specialize function template 'std::const_mem_fun1_t<_Result,_Ty,_Arg> std::mem_fun(_Result (_Ty::* )(_Arg) const)'
With the following template arguments:
'void'
'main::X'
'int &'
或者在 gcc 4.3.4 下出现此错误
error: no matching function for call to ‘mem_fun(void (main()::X::*)(int&))’
有趣的是,即使语言扩展启用了,VC9 / VC10 仍然对上面的例子感到窒息:
error C2535: 'void std::binder1st<_Fn2>::operator ()(int &) const' : member function already defined or declared
那么,标题中所述的功能是否可以以某种方式实现?或者我在最后一个例子中使用时犯了错误std::bind1st
or std::mem_fun
?