编写此类代码是否正确:
class A
{
private:
int m_int;
public:
void foo()
{
int a = 1;
int b = 2;
int c = 3;
float f = 3.14f;
std::string s("Something");
const auto f1 = [=] ()
{
// use only a, b, c
int d = a + b + c;
const auto f2 = [=]
{
// use f, s and also d
std::cout << f << s << d ;
}
};
}
};
问题是内部lambda使用了一些外部不需要的变量。如果这是无效的,那我应该怎么写?
注意:我也可以捕获指针变量。因此,a
,b
,c
,f
和s
也可以成为指针。
答案 0 :(得分:4)
有问题的代码(尽管内部lambda声明中的拼写错误)是正确的。由于第一个lambda将从封闭函数中捕获所有内容,因此第二个lambda将通过“捕获全部”封闭的lambda来访问它。
答案 1 :(得分:2)
根据C ++标准(5.1.2 Lambda表达式)
9一个lambda表达式,其最小的封闭范围是块范围 (3.3.3)是局部lambda表达式;任何其他lambda表达式 不应该有捕获默认或简单捕获 λ-介绍人。本地lambda表达式的范围是 封闭范围的集合,包括最里面的 封闭功能及其参数。 [注意:此范围 包括任何介入的lambda表达式。 - 后注]
因此第二个lambda的到达范围是成员函数foo()
的范围。由于lambda表达式具有默认捕获,因此它可以捕获此范围内的局部变量。
同样重要的是要注意同一部分第13段的以下部分
13 ...如果lambda表达式捕获实体并且该实体是 未在紧邻的lambda表达式中定义或捕获 或功能,该程序是不正确的。
在您的示例中,封闭的lambda使用默认捕获从函数块作用域隐式捕获内部lambda的所有必需变量。
答案 2 :(得分:0)
引自http://en.cppreference.com/w/cpp/language/lambda
[=]捕获在体内使用的所有自动变量 lambda by value
因为您在foo
中捕获了 f1
的所有变量,所以在f2
中使用它们没有问题。
所以它是有效的,尽管你可能想考虑通过引用来捕获它们。
答案 3 :(得分:0)
这将有效,因为您通过键入 [=] 按值捕获所有局部变量。因此f,s和d将在f2中可见,但它只是副本,而不是实际变量