第一个代码段编译时没有任何警告(实例):
#includestruct A { constexpr A(): i(5){} constexpr operator int() { return 5; } int i; }; int main() { A a; int b[a]{ 0, 1, 2, 3, 4 }; std::cout << b[4] << '\n'; }
现在通过返回i
转换运算符(实例)来改变上面的代码段:
constexpr operator int() { return i; }
海湾合作委员会警告说这b
是一个VLA.
对我来说,这两个变体似乎都符合C++ 14中的段落§5.19[expr.const]/3.
您正在执行ltr转换i
,但是对于[expr.const] /(2.7)这里不违反,(2.7.3)必须适用:
(2.7.1)涉及完整的对象,(2.7.2)谈论字符串文字,(2.7.4)是关于生命在表达式的评估中开始的对象 - 不适用,因为a
声明先于b
.
定义a
为constexpr
,代码兼容.
澄清标准内容的一个小附录:括号内的表达式必须是类型std::size_t
([dcl.array]/1)的转换常量表达式,在[expr.const]/4中定义为
甲类型的转换后的常量表达式
T
是一个表达式,隐式转换为类型T
,其中,所述转换后的表达式是一个常量表达式和[...被满足的要求...]
因此,实际上,标准是否感兴趣
constexpr std::size_t s = a;
是有效的.由于上述原因,它不是 - 试图使用先前定义的非constexpr
对象的子对象.