Vit*_*meo 12 c++ lambda language-lawyer trailing-return-type c++14
int main()
{
auto l = [x = 10]() -> decltype(x) {};
}
Run Code Online (Sandbox Code Playgroud)
clang ++ 4.0拒绝此代码时出现以下错误:
error: use of undeclared identifier 'x'
auto l = [x = 10]() -> decltype(x) {};
^
Run Code Online (Sandbox Code Playgroud)g ++ 7拒绝此代码时出现以下错误:
In function 'int main()':
error: 'x' was not declared in this scope
auto l = [x = 10]() -> decltype(x) {};
^
error: 'x' was not declared in this scope
In lambda function:
warning: no return statement in function returning non-void [-Wreturn-type]
auto l = [x = 10]() -> decltype(x) {};
^
Run Code Online (Sandbox Code Playgroud)这是一个错误还是标准中有一些东西明确阻止使用C++ 14通用语法捕获的对象在lambda的尾随返回类型中使用?
请注意,两个编译器都对非泛化捕获很满意:
int main()
{
int x = 10;
auto l = [x]() -> decltype(x) { return 0; };
}
Run Code Online (Sandbox Code Playgroud)
TL; DR:编译器的行为与预期一致.
该标准定义了lambda语义,如下所示[expr.prim.lambda,section 1]:
λ-表达:
Run Code Online (Sandbox Code Playgroud)lambda-introducer lambda-declarator_opt compound-statement
这里复合语句只是{}之间lambda的主体,因为lambda-declarator中包含了其他所有内容:
拉姆达声明符:
Run Code Online (Sandbox Code Playgroud)( parameter-declaration-clause ) decl-specifier-seq_opt exception-specification_opt attribute-specifier-seq_opt trailing-return-type_opt
另外,在同一章的第12节中,也就是说
init-capture的行为就像它声明并显式捕获"auto init-capture;"形式的变量一样,其声明区域是lambda-expression的复合语句,除了:
(12.1) - 如果捕获是通过复制(见下文),为捕获声明的非静态数据成员和变量被视为引用同一对象的两种不同方式,它具有非静态的生命周期数据成员,不执行其他复制和销毁,以及
(12.2) - 如果捕获是通过引用,变量的生命周期在闭包对象的生命周期结束时结束.
因此,在您的第一个示例中,变量xscope仅是lambda主体,不包括decltype表达式.在第二个例子中,显然,x范围是函数main.