Lambda捕获 C++14

10

我遇到了这样一种记号:

int x = 4;
auto y = [&r = x, x = x+1]()->int { 
    r += 2;
    return x+2;
}();

你能解释一下这个语句吗?我之前使用的是C++03,最近升级到了C++11。从今天开始我开始使用C++14,并遇到了这段代码片段。

谢谢!


3
C++14中引入了Lambda捕获表达式的特性。Lambda函数可以捕获其定义范围内的变量,并在函数体中使用它们。这个特性还包括了初始化捕获变量的方式。您也可以查看提案文档:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3610.html。 - chris
哇,这个语法真的很混乱。 - Quentin
3
我不确定这个问题如何对其他人有所帮助。它并不容易被搜索到... - Lightness Races in Orbit
1
@LightnessRacesinOrbit 如果您认为这个问题需要编辑以便于搜索(添加可搜索的关键词),您可以进行编辑。 - Kaidul
2
@KaidulIslam:不,只有你能进一步解释代码中令你困惑的部分。此外,提出一个好问题是你的责任! - Lightness Races in Orbit
4
不确定为什么这个问题被踩了。并不是每个人都知道C++14将会有哪些新功能。 - jliv902
2个回答

8

感谢 @chris 提供的 wikipedia 参考资料。我发现的是 -

这里有一个很好的解释,适用于不了解 C++11 旧 lambda 捕获的人

在 C++14 中:


C++11 lambda functions capture variables declared in their outer scope by value-copy or by reference. This means that value members of a lambda cannot be move-only types. C++14 allows captured members to be initialized with arbitrary expressions. This allows both capture by value-move and declaring arbitrary members of the lambda, without having a correspondingly named variable in an outer scope.

This is done via the use of an initializer expression:

auto lambda = [value = 1] {return value;};

The lambda function lambda will return 1, which is what value was initialized with. The declared capture deduces the type from the initializer expression as if by auto.

This can be used to capture by move, via the use of the standard std::move function:

std::unique_ptr<int> ptr(new int(10));
auto lambda = [value = std::move(ptr)] {return *value;};

所以上述表达式将x更新为6,并初始化y为7。

我不会说y被初始化为7,因为它是一个lambda函数。 - tgmath
Lambda表达式会立即被执行,因此y被初始化。 - Ben Hymers
如果有人想要给出详细的解释,请发布一个答案。只有当有人能够给出更多的直觉时(因为这是我的自己的答案),我才会接受这个答案。 - Kaidul

1
这个例子是C++14特性“Lambda capture Initializers”的一部分,它允许创建使用任意表达式初始化的lambda捕获。使用这种引用捕获,可以使用不同于被引用变量的名称。
如果您运行您的代码:
int x = 4;
auto y = [&r = x, x = x+1]()->int { 
    r += 2; //r=6
    return x+2;//5+2
};
cout<<y()<<endl; // this will print 7

另一个例子,通过这个你将会得到清晰的图片。 - Ramanand Yadav
#include<iostream> using namespace std;int main() { auto x = 1; auto f = [&r = x, x = x * 10] { ++r; return r + x; }; cout<<f()<<endl; } - Ramanand Yadav

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接