是否可以在 C++11 之前创建函数局部闭包?

2024-04-16

借助 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?


bind1st只适用于二元函数,并且一般来说它非常受限制。mem_fn仅适用于非静态成员函数;对于您的应用程序,您想要ptr_fun.

实际上,C++03 中这项工作的最佳工具是 Boost Bind,或者我将在这里演示tr1::bind(在我看来)这更便携。

#include <tr1/functional>
#include <iostream>
#include <algorithm>

using namespace std::tr1::placeholders;

int nums[] = { 1, 2, 4, 5, 6, 8 };

int main() {
    struct is_multiple {
        static bool fn( int mod, int num ) { return num % mod == 0; }
    };

    int *n = std::find_if( nums, nums + sizeof nums/sizeof*nums,
                        std::tr1::bind( is_multiple::fn, 3, _1 ) );

    std::cout << n - nums << '\n';
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以在 C++11 之前创建函数局部闭包? 的相关文章

随机推荐