繁体   English   中英

MSVC vs GCC & Clang 使用 lambda 时的错误

[英]MSVC vs GCC & Clang Bug while using lambdas

我正在尝试在CppCon上展示的一个使用lambdas的示例。 令我惊讶的是,该程序没有在 gcc 和 clang 中编译(在 C++14 或 C++17 中),而是在 msvc 中编译。 这可以在这里验证。

作为参考,示例代码如下:

#include <stdio.h>

int g = 10;
auto kitten = [=]() { return g+1; };
auto cat = [g=g]() { return g+1; };

int main() {
    g = 20;
    printf("%d %d\n", kitten(), cat());
}

这里有什么问题(如果有的话),哪个编译器是正确的?

请注意,该代码是从他们的官方演示幻灯片中精确复制粘贴的。

这是 MSVC 的问题。 clang 和 g++ 是正确的。

来自[expr.prim.lambda.capture]/3 (C++17 草案 N4659)

其最小封闭 scope 是块 scope (6.3.3) 的 lambda 表达式是本地 lambda 表达式; 任何其他 lambda 表达式在其 lambda 引入器中不得有捕获默认或简单捕获。 局部 lambda 表达式的到达 scope 是封闭范围的集合,直到并包括最里面的封闭 function 及其参数。 [注意:达到 scope 包括任何中间的 lambda 表达式。 ——尾注]

由于=capture-default ,并且 lambda 不在块范围内,因此代码无效。

这里有什么问题(如果有的话)

让我们问一下拒绝编译的编译器有什么要说的:

 error: non-local lambda expression cannot have a capture-default

让我们看看标准是怎么说的:

C++14 草案 N4140

最小封闭 scope 是块 scope ([basic.scope.block]) 的 lambda 表达式是一个局部 lambda 表达式; 任何其他 lambda 表达式在其 lambda 引入器中不得有捕获默认或简单捕获。 局部 lambda 表达式的到达 scope 是封闭范围的集合,直到并包括最里面的封闭 function 及其参数。 [注意:达到 scope 包括任何中间的 lambda 表达式。 ——尾注]


最新草案

lambda 表达式在其 lambda 引入器中不应包含捕获默认值或简单捕获,除非其最内层的封闭 scope 是一个块 scope([basic.scope.block])或者它出现在默认成员初始化器及其最内层的封闭scope对应的是class scope([basic.scope.class])。

C++17 的措辞与 C++14 几乎相同。

程序格式错误,诊断消息正确。 不诊断格式错误的编译器(icc、msvc)不符合标准。


该程序可以简单地通过删除 capture-default 来修复。 无论如何,它无法捕获块 scope 之外的任何内容,这使得它无用,这就是为什么不允许它。 可以在不捕获它们的情况下访问诸如::g之类的全局变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM