【发布时间】:2011-04-19 22:45:15
【问题描述】:
使用 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 和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 或std::mem_fun 时犯了错误?
【问题讨论】:
-
std::mem_fn(&X::functor)阻塞,因为functor不是成员函数,它是静态的。 -
@GMan:不,不是在最后一个例子中。
-
@Xeo:对不起,我的意思是回答“但不幸的是 std::mem_fun 不知何故窒息......”,在第二个。
-
@Xeo:它必须是静态的,否则你最终会得到一个指向本地成员类型的指针,这不是一个有效的模板参数。请改用
std::ptr_fun,并使用bind_1st传递实际捕获的值,而不是本地类型的实例。 -
@GMan:啊,是的,应该有一个新段落和一个双冒号,对不起。
标签: c++ function closures local functor