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

Par*_*ngh 48 c++ closures lexical-closures

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

Ape*_*ime 40

最新的C++标准C++ 11具有闭包功能.

http://en.wikipedia.org/wiki/C%2B%2B11#Lambda_functions_and_expressions

http://www.cprogramming.com/c++11/c++11-lambda-closures.html

  • @StefanSteiger 我想 Rust 闭包也不是真正的闭包?他们就是这样。C++11 是否实现了一些接口,以便可以动态调用它们,类似于 Rust 中的“dyn Fn(x) -> y”? (4认同)
  • 不,我们不。在C ++中,所有闭包都是传递过来的隐藏类的成员函数。而且,由于传递了一个类,因此函数特性不兼容。是的,我们有点闭包,但它们不是实际的闭包,它们不是可以访问其他一些函数变量,被分配且其地址可以传递的函数。既不使用bind也不使用lambda表达式。而且Visual Studio / VisualCPP不支持alloc_callback,它在C语言中用于执行此操作。而且,您不能将成员函数传递给需要静态函数的函数。 (3认同)

Zri*_*rin 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;
Run Code Online (Sandbox Code Playgroud)

下一个修改其状态:

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;
Run Code Online (Sandbox Code Playgroud)

内部状态不能从外部引用(访问).

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

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

  • 行为类似于闭包,但我不会说它是一个闭包. (6认同)
  • 这看起来很像一个闭包,你在这里只是一个持有由方法修改的状态的对象,加上一些语法糖,因为它是"operator()"而不是任何其他方法.让它返回一个取决于状态的lambda,或者返回方法的参数,然后我们正在谈论. (5认同)
  • @dividebyzero 一件事是闭包的抽象概念,另一件事是您如何在编程语言中使用该想法。在上面的例子中,“my_add_3_closure”和“adder”都是闭包——它们与定义相匹配。这里的对象实际上是对函数的引用……我想强调的是,在 C++11 之前很久就在 C++ 编程中使用了闭包的想法,而新的 lambda 构造只是让它变得更容易。 (3认同)
  • @Stepenre 有什么区别? (2认同)
  • @AnthonyMonterrosa,你的论点犯了一个错误。private: int sum 表示该成员只能由成员函数访问,但它仍然属于实例,而不属于类。`static int sum` 将属于该类。 (2认同)

Set*_*nre 14

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

#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
}
Run Code Online (Sandbox Code Playgroud)

我忘记了mutable关键字引入了一个未定义的行为(clang版本返回了一个垃圾值).实施后,关闭工作正常(在海湾合作委员会和铿锵声)


Jam*_*nze 8

我怀疑这取决于你关闭的意思.我一直使用的含义意味着某种垃圾收集(虽然我认为可以使用引用计数来实现); 与其他语言中的lambdas不同,它捕获引用并使引用的对象保持活动状态,C++ lambdas要么捕获一个值,要么引用的对象 不能保持活动状态(并且引用很容易悬挂).


Ros*_*ost 7

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

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