使用 lambda 捕获的 constexpr 值作为数组维度
Using lambda captured constexpr value as an array dimension
GCC
和 Clang
编译以下代码:
void Test()
{
constexpr int Size = 3;
auto Lambda = [Size]{ int Dim[Size]; };
}
然而,VisualStudio 2015 CTP 6
没有。尽管如此,所有 3 个编译器都对这段代码感到满意:
void Test()
{
static constexpr int Size = 3;
auto Lambda = []{ int Dim[Size]; };
}
哪个片段实际上是以正确的方式进行的? C++ 标准怎么说?
此问题与Lambda capturing constexpr object
相关
C++11 [expr.prim.lambda]/12
If a lambda-expression odr-uses this or a variable with automatic storage duration from its reaching scope, that entity shall be captured by the lambda-expression.
和/17
Every id-expression that is an odr-use of an entity captured by copy is transformed into an access to the corresponding unnamed data member of the closure type. [ Note: An id-expression that is not an odr-use
refers to the original entity, never to a member of the closure type. [...]
— end note ]
所以我们甚至不需要在第一个示例中捕获 Size
(它不是 static
),因为从该变量读取不是 odr-use,因为它可以出现在常量表达式中,左值到右值的转换立即应用于它,[basic.def.odr]/2
A variable whose name appears as a potentially-evaluated expression is odr-used unless it is an object that satisfies the requirements for appearing in a constant expression and the lvalue-to-rvalue
conversion is immediately applied.
(我不清楚数组边界是否需要 l-t-r 转换。)
同样适用于通过引用捕获 Size
时,或显式(通过复制)捕获 Size
但不使用它时:使用 id-expression Size
在 lambda 中访问在 Test
中声明的 constexpr
变量,而不是任何捕获的成员(对于复制捕获:IFF 访问不构成 odr-使用).
C++14 [expr.prim.lamda]/12 添加了一些与这里无关的多态 lambda 的措辞,并将 /17 移动到 /18。 odr-use 的规则更复杂,但我认为出于相同的根本原因(读取编译时常量),它不是 odr-use。
GCC
和 Clang
编译以下代码:
void Test()
{
constexpr int Size = 3;
auto Lambda = [Size]{ int Dim[Size]; };
}
然而,VisualStudio 2015 CTP 6
没有。尽管如此,所有 3 个编译器都对这段代码感到满意:
void Test()
{
static constexpr int Size = 3;
auto Lambda = []{ int Dim[Size]; };
}
哪个片段实际上是以正确的方式进行的? C++ 标准怎么说?
此问题与Lambda capturing constexpr object
相关C++11 [expr.prim.lambda]/12
If a lambda-expression odr-uses this or a variable with automatic storage duration from its reaching scope, that entity shall be captured by the lambda-expression.
和/17
Every id-expression that is an odr-use of an entity captured by copy is transformed into an access to the corresponding unnamed data member of the closure type. [ Note: An id-expression that is not an odr-use refers to the original entity, never to a member of the closure type. [...] — end note ]
所以我们甚至不需要在第一个示例中捕获 Size
(它不是 static
),因为从该变量读取不是 odr-use,因为它可以出现在常量表达式中,左值到右值的转换立即应用于它,[basic.def.odr]/2
A variable whose name appears as a potentially-evaluated expression is odr-used unless it is an object that satisfies the requirements for appearing in a constant expression and the lvalue-to-rvalue conversion is immediately applied.
(我不清楚数组边界是否需要 l-t-r 转换。)
同样适用于通过引用捕获 Size
时,或显式(通过复制)捕获 Size
但不使用它时:使用 id-expression Size
在 lambda 中访问在 Test
中声明的 constexpr
变量,而不是任何捕获的成员(对于复制捕获:IFF 访问不构成 odr-使用).
C++14 [expr.prim.lamda]/12 添加了一些与这里无关的多态 lambda 的措辞,并将 /17 移动到 /18。 odr-use 的规则更复杂,但我认为出于相同的根本原因(读取编译时常量),它不是 odr-use。