constexpr数组成员是否编译时间常数?

constexpr数组成员是否编译时间常数?

问题描述:

是代码片段

struct Parameters {
   static constexpr int n = 2;
   static constexpr double v[n] = {4.0, 5.0};
};

合法的C ++ 11?并且,如果是,则 Parameters :: v [0] Parameters :: v [1] 编译时间常数还是仅仅是指针 Parameters :: v 本身就是 constexpr (无论在编译时意味着什么)?

legal C++11? And, if so, are Parameters::v[0] and Parameters::v[1] compile time constants or is just the pointer Parameters::v itself a constexpr (whatever that would mean at compile time)?

如您所见,我通常对 constexpr 数组及其在类/结构中的初始化有些困惑。请随时回答我的特定问题,并提及与该主题相关的常见陷阱。

As you can see I am generally a bit confused about constexpr arrays and their initialization in classes/structs. Please feel free to not only answer my specific question but also to mention common pitfalls and the like concerning this topic.

构造没有问题。引用C ++ 11, [dcl.constexpr]

I see no problem with the construct. Quoting C++11, [dcl.constexpr]:


§1 constexpr 说明符仅适用于变量的定义,函数的声明或
函数模板或文字常量的静态数据成员的声明类型(3.9)。 ...

§1 The constexpr specifier shall be applied only to the definition of a variable, the declaration of a function or function template, or the declaration of a static data member of a literal type (3.9). ...

§9对象声明中使用的 constexpr 说明符将对象声明为 const 。这样的对象应具有
文字类型,并应进行初始化。如果是通过构造函数调用初始化的,则该调用应为常量
表达式(5.19)。否则,或者如果在引用声明中使用constexpr说明符,则出现在其初始化程序中的每个完整表达式
都应为常量表达式。
中用于转换初始值设定项表达式的每个隐式转换以及用于初始化的每个构造函数调用均应是常量表达式(5.19)中允许的
之一。

§9 A constexpr specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized. If it is initialized by a constructor call, that call shall be a constant expression (5.19). Otherwise, or if a constexpr specifier is used in a reference declaration, every full-expression that appears in its initializer shall be a constant expression. Each implicit conversion used in converting the initializer expressions and each constructor call used for the initialization shall be one of those allowed in a constant expression (5.19).

double 是文字类型,因此也是文字类型数组。这意味着代码中的 v [0] v [1] 确实是常量表达式。

double is a literal type, and so is an array of literal types. Which means that v[0] and v[1] from your code are indeed constant expressions.