问题描述
GCC
和锵
做编译下面code:
GCC
and Clang
do compile the following code:
void Test()
{
constexpr int Size = 3;
auto Lambda = [Size]{ int Dim[Size]; };
}
然而,的VisualStudio 2015年CTP 6
没有。不过,所有3编译器很高兴与此code:
However, VisualStudio 2015 CTP 6
does not. Nevertheless, all 3 compilers are happy with this code:
void Test()
{
static constexpr int Size = 3;
auto Lambda = []{ int Dim[Size]; };
}
这片段是实际上做它的正确方法是什么?什么是C ++标准说什么?
Which snippet is actually doing it in the correct way? What does the C++ standard say?
此问题是关系到
推荐答案
C ++ 11 [expr.prim.lambda] / 12
C++11 [expr.prim.lambda]/12
如果一个lambda-EX pression ODR-使用这个或与它的深远范围自动存储时间的变量,该实体应当由λ-EX pression抓获。
和/ 17
每 ID-前pression 的是一个ODR使用由拷贝捕获的实体转化为到封闭类型的相应无名数据成员的存取。 [注:的一个的 ID-EX pression 的不是一个ODR使用
指的是原始的实体,从未封闭类型的成员。 [...]
- 注完的]
所以我们甚至都不需要捕获尺寸
在第一个例子(它不是静态
)因为从变量读取不是ODR使用,因为它可以出现在一个恒定的前pression和左值到右值转换立即适用于它,[basic.def.odr] / 2
So we don't even need to capture Size
in the first example (where it is not static
), since reading from that variable is not an odr-use since it can appear in a constant expression and the lvalue-to-rvalue conversion is immediately applied to it, [basic.def.odr]/2
一个变量,其名称显示为一个潜在的评估前pression是ODR使用的,除非它是满足了出现在一个恒定的前pression的要求和左值到右值对象
转换立即生效。
(这是我不明白,如果数组边界需要一个l-T-R的转换,虽然。)
(It is not clear to me if the array bounds require an l-t-r conversion, though.)
同样捕获尺寸
引用,或捕获尺寸
明确(通过复制),但不ODR时,当适用 - 使用它:使用的 ID-EX pression 的尺寸
内拉姆达访问 constexpr
变量测试,没有任何捕获部件(捕获逐副本:IFF访问并不构成ODR使用)。
The same applies when capturing Size
by reference, or when capturing Size
explicitly (by copy) but not odr-using it: the use of the id-expression Size
within the lambda accesses the constexpr
variable declared in Test
, not any captured member (for capture-by-copy: IFF the access does not constitute an odr-use).
C ++ 14 [expr.prim.lamda] / 12添加了一些措辞多态lambda表达式是这里无关紧要,并且移动/ 17/18。对于ODR使用的规则更加复杂,但我要说这不是一个ODR使用了相同的底层原因(读编译时间常数)。
C++14 [expr.prim.lamda]/12 adds some wording for polymorphic lambdas that is irrelevant here, and moves /17 to /18. The rules for odr-use are more complicated, but I'd argue it's not an odr-use for the same underlying reason (reading a compile-time constant).
这篇关于使用lambda捕捉constexpr值作为数组维的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!