我正在阅读网上关闭的内容。我想知道C ++是否有一个内置的闭包工具,或者我们是否可以用C ++实现闭包?
答案 0 :(得分:37)
最新的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
答案 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)))))