C++语言中的闭包

来源:互联网 发布:数据备份方案 编辑:程序博客网 时间:2024/06/15 09:14

    在大多数函数式语言中,不允许函数有副作用,即函数不能访问或改变外部状态(比如全局变量),这样做极大方便了单元测试和bug 定位以及并发,但是在一些函数式语言中对函数副作用的要求稍稍放宽了限制,引入了词法闭包(lexical closure),允许函数可以保留自己的context, 以便设计出传出值是函数的函数。例如:

    erlang中这样实现闭包,

    MakeTest = fun(L) -> (fun(X) -> lists:member(X,L) end) end. 

    要使用这个闭包,

    Fruit = [apple, pear, orange].

    IsFruit = MakeTest(Fruit).

    测试如下:

        IsFruit(pear)返回true

        IsFruit(apple)返回true

        IsFruit(dog)返回false

    闭包得巧妙之处就在于MakeTest已经返回了但是其参数Fruit依然被IsFruit保存在自己的上下文中,并在接卸来的调用中使用。

    其实在C++中也可以实现这样的机制,而且多年之前就广泛使用了。

    接下来实现一个相同功能的C++版本.

  1. template<class TContainer>
  2. struct Closure
  3. {
  4. public:
  5.  Closure(TContainer const& c):mCollection(c)
  6.  {
  7.  }
  8. public:
  9.  bool operator()(typename TContainer::value_type const& val)
  10.  {
  11.   typename TContainer::iterator i = std::find(mCollection.begin(), mCollection.end(), val);
  12.   return i != mCollection.end();
  13.  }
  14. private:
  15.  TContainer mCollection;
  16. };
  17. template<class TContainer>
  18. Closure<TContainer> MakeTest(TContainer& c)
  19. {
  20.  return Closure<TContainer>(c);
  21. }
  22. int _tmain(int argc, _TCHAR* argv[])
  23. {
  24.  enum Fruit{apple, pear, orange};
  25.  enum Animal{dog = 100};
  26.  std::vector<int> v;
  27.  v.push_back(apple);
  28.  v.push_back(pear);
  29.  v.push_back(orange);
  30.  Closure<std::vector<int> > IsFruit = MakeTest(v);
  31.  bool bRet = IsFruit(pear);
  32.  bRet = IsFruit(apple);
  33.  bRet = IsFruit(dog);
  34.  return 0;
  35. }
原创粉丝点击