我们在 C++ 中有闭包吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12635184/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Do we have closures in C++?
提问by Parvinder Singh
I was reading about closures on the net. I was wondering if C++ has a built-in facility for closures or if there is any way we can implement closures in C++?
我正在网上阅读有关关闭的信息。我想知道 C++ 是否有用于闭包的内置工具,或者是否有任何方法可以在 C++ 中实现闭包?
采纳答案by Apeirogon Prime
The latest C++ standard, C++11, has closures.
最新的 C++ 标准C++11有闭包。
http://en.wikipedia.org/wiki/C%2B%2B11#Lambda_functions_and_expressions
http://en.wikipedia.org/wiki/C%2B%2B11#Lambda_functions_and_expressions
http://www.cprogramming.com/c++11/c++11-lambda-closures.html
http://www.cprogramming.com/c++11/c++11-lambda-closures.html
回答by Zrin
If you understand closure as a reference to a function that has an embedded, persistent, hidden and unseparable context (memory, state), then 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 closure
int x = 4;
int y = my_add_3_closure(x);
std::cout << y << std::endl;
The next one modifies its state:
下一个修改它的状态:
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;
The inner state can not be referenced (accessed) from outside.
内部状态不能从外部引用(访问)。
Depending on how you define it, a closure can contain a reference to more than one function or, two closures can share the same context, i.e. two functions can share the same persistent state.
取决于您如何定义它,一个闭包可以包含对多个函数的引用,或者两个闭包可以共享相同的上下文,即两个函数可以共享相同的持久状态。
Closure means not containing free variables - it is comparable to a class with only private attributes and only public method(s).
闭包意味着不包含自由变量——它相当于一个只有私有属性和只有公共方法的类。
回答by Setepenre
Yes, This shows how you could implement a function with a state without using a functor.
是的,这显示了如何在不使用函子的情况下实现带有状态的函数。
#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
}
I forgot the mutable keyword which introduced an undefined behaviour (clang version was returning a garbage value). As implemented, the closure works fine (on GCC and clang)
我忘记了引入未定义行为的 mutable 关键字(clang 版本返回垃圾值)。实施后,关闭工作正常(在 GCC 和 clang 上)
回答by James Kanze
I suspect that it depends on what you mean by closure. The meaning I've always used implies garbage collection of some sort (although I think it could be implemented using reference counting); unlike lambdas in other languages, which capture references and keep the referenced object alive, C++ lambdas either capture a value, or the object refered to is notkept alive (and the reference can easily dangle).
我怀疑这取决于你所说的闭包是什么意思。我一直使用的意思意味着某种垃圾收集(尽管我认为它可以使用引用计数来实现);与其他语言中的 lambda 捕获引用并使被引用对象保持活动状态不同,C++ lambdas 要么捕获一个值,要么所引用的对象 不保持活动状态(并且引用很容易悬垂)。
回答by Rost
Yes, C++11 has closures named lambdas.
是的,C++11 有名为lambdas 的闭包。
In C++03 there is no built-in support for lambdas, but there is Boost.Lambdaimplementation.
在 C++03 中没有对 lambdas 的内置支持,但有Boost.Lambda实现。
回答by Mark Yang
Strictly speaking. 'Closure' is LISP only. Use Let returns lambda as last commands. 'Let Over Lambda'. This is possible only for LISP because of infinite scope with lexical scoping. I don't know any other language support this natively until know.
严格来讲。“关闭”仅适用于 LISP。使用 Let 返回 lambda 作为最后一个命令。'放过 Lambda'。由于词法范围的无限范围,这仅适用于 LISP。在知道之前,我不知道任何其他语言本身支持这一点。
(defun my-closure ()
(let ((cnt 0))
(lambda ()
(format t "called : ~A times" (incf cnt)))))