但它在gcc 4.9.0中编译.查看实例:
#includestruct A { constexpr A(): i(5) {} int&& f() { return std::move(i); } int i; } a; A&& f(A& a) { return std::move(a); } int main() { A a; int b[a.f()]{ 0, 1, 2, 3, 4 }; std::cout << b[4] << '\n'; }
从§5.19/ 3开始,我们有:
整数常量表达式是整数或未整数枚举类型的表达式,隐式转换为prvalue,其中转换后的表达式是核心常量表达式.[注意:这些表达式可以用作数组边界(8.3.4,5.3.4),比特字段长度(9.6),如果基础类型不固定(7.2),则作为枚举器初始化器,以及作为比对(7.6). 2). - 尾注]
表达式a.f()
是整数类型的表达式.在我看来(虽然我需要对这一点进行一些澄清)这个表达式也可以转换为prvalue,因为它是一个xvalue.但是我觉得这里真正的问题是,表达a.f()
是不是一个核心的常量表达式,它满足在§5.19/ 2弹点(2.1).
§5.19/ 2:
条件表达式
e
是核心常量表达式,除非按照e
抽象机器(1.9)的规则评估以下表达式之一:(2.1) -
this
(5.1.1),除了constexpr
作为一部分进行评估的函数或constexpr构造函数之外e
;
eerorika.. 7
你是对的,a.f()
不是一个恒定的表达.c ++标准不允许使用可变长度数组.但是,GNU编译器支持它们作为语言扩展.当您使用带有该-pedantic
选项的非标准扩展或错误时,您可以要求编译器发出警告-pedantic-errors
.
编辑:显然,GCC 4.9 增加了对N3639的官方支持,即将可变长度数组添加到C++ 14标准的提议.最后,该提案未包含在标准中,但GCC 4.9在C++ 14之前发布,因此未反映出更改.因此,在C++ 14模式下,GCC 4.9支持VLA,上述选项不会禁用它们.请注意,C++ 14模式仍处于试验阶段(即使在GCC 5中).
你是对的,a.f()
不是一个恒定的表达.c ++标准不允许使用可变长度数组.但是,GNU编译器支持它们作为语言扩展.当您使用带有该-pedantic
选项的非标准扩展或错误时,您可以要求编译器发出警告-pedantic-errors
.
编辑:显然,GCC 4.9 增加了对N3639的官方支持,即将可变长度数组添加到C++ 14标准的提议.最后,该提案未包含在标准中,但GCC 4.9在C++ 14之前发布,因此未反映出更改.因此,在C++ 14模式下,GCC 4.9支持VLA,上述选项不会禁用它们.请注意,C++ 14模式仍处于试验阶段(即使在GCC 5中).