我从另一篇文章中看到,c++11提供闭包功能。据我所知,闭包非常类似于具有私有成员和公共方法的对象。如果没有,那又有何不同呢?
发布于 2015-12-07 08:30:15
闭包是从外部范围访问引用/指针的函数或方法。
这是一个示例JavaScript闭包:
var a = "hello world";
function doStuff() {
console.log(a); // "a" variable from the outer scope
}在C++和世界上的其他编程语言中,闭包指的是相同的概念。
发布于 2015-12-07 08:45:27
闭包是一个潜在的有状态、可调用的对象。从概念上讲,它是一个函数加上一个外部状态的“环境”。
普通函数是无状态的,因为对函数的每一个引用都与对函数的任何其他引用一样好;除了函数的名称之外,没有任何东西可以区分函数。相反,可以(可能)复制闭包对象,并且这两个副本是不同的,其中一个不能替代另一个副本。
在函数是合法的“可变类型”或“对象”的编程语言中(与许多函数式语言一样),函数和闭包之间的区别要模糊得多,因为(视语言而定)在这种情况下的函数可能总是被视为带有它们的“环境”。
然而,在C++中,可调用对象类型有一个非常明确的定义,它是用户定义的类型,函数调用操作符过大,而C++11添加的新lambda表达式只是一种方便的机制,可以动态定义这些类型并创建合适的实例。
下面是一个可调用类型的示例:
struct Foo
{
Foo(int & acc) : acc_(acc), n_(0) {}
int n_;
int & acc_;
void operator()(char c)
{
n_ += std::is_digit(c) ? 1 : 2;
acc += n_;
}
};此类型的对象所持有的状态既包含内部数据成员(n_),也包含对在构造时提供的其他内容的引用。一种可能的用途是:
int bar(const std::string s)
{
int result = s.size();
std::for_each(s.begin(), s.end(), Foo(result));
return result;
}也就是说,我们构造一个Foo的临时实例,它的状态现在包括一个从0开始的内部计数器和一个对外部对象result的引用,它可以像一个接受单个char的函数一样被调用。对输入字符串s中的每个字符调用此可调用对象。
使用lambda表达式(实际上,是一个C++14 lambda表达式),我们可以在不定义类类型的情况下实现相同的结果。
std::for_each(s.begin(), s.end(),
[&result, n = 0](char c) mutable
{ n += std::is_digit(c) ? 1 : 2; result += n; });事实上,效果是完全相同的;闭包的类型基本上与Foo相同。lambda表达式的捕获列表(即方括号之间的所有内容)确定类型所拥有的两个数据成员并对它们进行初始化。例如,&result的存在意味着类型获得一个int &成员,并且它绑定到封闭作用域中的变量result。
https://stackoverflow.com/questions/34129196
复制相似问题