"Capture by move" 不阻止引用捕获

"Capture by move" does not prevent capture by reference

当我写[&,x](){ /* making use of x */ }时,x被值捕获。

当我写[=,&x](){ /* making use of x */ }时,x被引用捕获。

如果我尝试编写 [&x, x](){ … },我会收到一条错误消息,告诉我 x 只能在捕获列表中出现一次。

但是,[&x, y = std::move(x)](){ /* making use of x and y */ }(); 编译正常,但出现分段错误。

为什么代码甚至可以编译?为什么标准允许我通过引用捕获变量并且我还在“通过移动捕获”初始化捕获中使用它?

这种情况[&x, y = std::move(x)](){ };从编译器的角度来看是非常合法的,因为捕获使用了不同的标识符。标准如下:

[expr.prim.lambda/capture-2]

Ignoring appearances in initializers of init-captures, an identifier or this shall not appear more than once in a lambda-capture.

[&i, a = i]{ };    // OK
[&i, a = std::move(i)]{ };    // OK

[&i, i]{ };       // error: i repeat
[&i, i = std::move(i)]{ };    // error: i repeated