我们在C ++中有闭包吗?

时间:2012-09-28 07:05:03

标签: c++ closures lexical-closures

我正在阅读网上关闭的内容。我想知道C ++是否有一个内置的闭包工具,或者我们是否可以用C ++实现闭包?

6 个答案:

答案 0 :(得分:37)

答案 1 :(得分:18)

如果您将闭包理解为对具有嵌入式,持久性,隐藏且不可分离的上下文(内存,状态)的函数的引用,则为yes:

class add_offset {
private:
    int offset;
public:
    add_offset(int _offset) : offset(_offset) {}
    int operator () (int x) { return x + offset; }
}

// make a closure
add_offset my_add_3_closure(3);

// use cloure
int x = 4;
int y = my_add_3_closure(x);
std::cout << y << std::endl;

下一个修改其状态:

class summer
{
private:
    int sum;
public:
    summer() : sum(0) {}
    int operator () (int x) { return sum += x; }
}

// make a closure
summer adder;
// use closure
adder(3);
adder(4);
std::cout << adder(0) << std::endl;

无法从外部引用(访问)内部状态。

根据你如何定义它,闭包可以包含对多个函数的引用,或者两个闭包可以共享相同的上下文,即两个函数可以共享相同的持久性,...,状态。

Closure意味着不包含自由变量 - 它与只有私有属性且只有公共方法的类相当。

答案 2 :(得分:12)

是的,这显示了如何在不使用仿函数的情况下实现具有状态的函数。

#include <iostream>
#include <functional>


std::function<int()> make_my_closure(int x){
    return [x]() mutable {   
        ++x;
        return x;   
    };
}

int main()
{
    auto my_f = make_my_closure(10);

    std::cout << my_f() << std::endl; // 11
    std::cout << my_f() << std::endl; // 12
    std::cout << my_f() << std::endl; // 13

     auto my_f1 = make_my_closure(1);

    std::cout << my_f1() << std::endl; // 2
    std::cout << my_f1() << std::endl; // 3
    std::cout << my_f1() << std::endl; // 4

    std::cout << my_f() << std::endl; // 14
}

我忘记了mutable关键字引入了一个未定义的行为(clang版本返回了一个垃圾值)。 实施后,关闭工作正常(在GCC和clang上)

答案 3 :(得分:7)

是的,C ++ 11有一个名为lambdas的闭包。

在C ++ 03中,没有内置的lambdas支持,但实现了Boost.Lambda

答案 4 :(得分:7)

我怀疑这取决于你关闭的意思。我的意思 总是使用暗示某种垃圾收集(虽然我认为它 可以使用引用计数来实现);不像其他人的lambdas 语言,捕获引用并保留引用的对象 alive,C ++ lambda既可以捕获值,也可以捕获对象 保持活着(参考可以轻松摇晃)。

答案 5 :(得分:0)

严格来说。 “关闭”仅适用于LISP。使用Let返回lambda作为最后一个命令。 “放任Lambda”。由于词法作用域的作用域无限,因此这仅对LISP可行。我不知道其他语言是否支持它。

(defun my-closure ()
   (let ((cnt 0))
      (lambda () 
         (format t "called : ~A times" (incf cnt)))))
相关问题