在匿名联合成员的 lambda 表达式中捕获

Fed*_*dor 5 c++ lambda unions language-lawyer

众所周知,匿名联合是一个未命名的联合定义,它不会同时定义任何变量。匿名联合的成员被注入到封闭的范围内。但是在 lambda 表达式中捕获这些成员有什么限制吗?

在下面的示例程序中

int main() {
    union {
        int x{0};
        char y[4];
    };

    // error everywhere
    //[=]() { return x; };    
    //[&]() { return x; };

    // ok in GCC only
    [x]() { return x; };
    [&x]() { return x; };

    // ok in all
    [x=x]() { return x; };
    [&x=x]() { return x; };
}
Run Code Online (Sandbox Code Playgroud)

所有编译器都拒绝进行隐式捕获(通过值[=]和引用[&])。例如 Clang 的错误是

unnamed variable cannot be implicitly captured in a lambda expression
Run Code Online (Sandbox Code Playgroud)

至于显式捕获(通过值[x]和通过引用[&x]),编译器在这里存在分歧。MSVC 打印相同的错误:

error C3492: 'x': you cannot capture a member of an anonymous union
Run Code Online (Sandbox Code Playgroud)

Clang 的错误发生了变化并且变得不太清楚:

'x' in capture list does not name a variable
Run Code Online (Sandbox Code Playgroud)

GCC 允许在没有任何警告的情况下显式捕获。在线演示: https: //gcc.godbolt.org/z/Ghq66rjfW

这里是哪个编译器?

use*_*522 5

CWG 1612的缺陷报告和决议意味着不允许捕获匿名联盟的任何成员,无论是通过复制还是引用,无论是隐式还是显式。

请参阅后 C++20 草案 N4868 中的[expr.prim.lambda.capture]/10[expr.prim.lambda.capture]/12等:

[...] 匿名工会的成员不得被复制捕获。

[...] 位字段或匿名联合的成员不应通过引用捕获。