gpt4 book ai didi

c++ - 静态常量声明,变量的 constexpr 定义,有效的 C++?

转载 作者:可可西里 更新时间:2023-11-01 17:44:27 28 4
gpt4 key购买 nike

例子:在头文件中:

class Foo
{
static const int IntArray[];
};

在源文件中:

constexpr int Foo::IntArray[] = { 1, 2, 3, 4 };

这在 g++ 上编译并允许我将初始化列表放在源文件中而不是头文件中。 (如果它在 header 中是 constexpr,则编译器需要在 header 中立即初始化)。同时仍然允许在 constexpr 评估中使用数组...

这是有效的、可移植的 C++ 吗?

最佳答案

正确的方法

在我们开始语言代理之前,正确的做法是反过来做。在头文件中:

class Foo
{
static constexpr int IntArray[] = { 1, 2, 3, 4 };
};

然后在源文件中:

constexpr int Foo::IntArray[];

如果您在类定义中声明了一个static constexpr 类数据成员,您必须立即对其进行初始化。这对于 static const 数据成员是可选的。如果您在程序的任何地方使用 static constexpr 数据成员,您必须在同一个源文件中给出与上面类似的定义,并且没有初始化程序。

标准(草案)的内容

问题中的示例代码风格不佳,显然至少有一个编译器拒绝它,但它实际上似乎符合 C++14 草案标准。 [ dcl/constexpr ] 说:

The constexpr specifier shall be applied only to the definition of a variable or variable template, the declaration of a function or function template, or the declaration of a static data member of a literal type. If any declaration of a function, function template, or variable template has a constexpr specifier, then all its declarations shall contain the constexpr specifier.

请注意,由于遗漏,其声明并非都需要包含 constexpr 说明符。

稍后在同一部分:

A constexpr specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized. [...]

但另见 [ class.static.data ]:

If a non-volatile const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [Note: In both these cases, the member may appear in constant expressions. — end note ] The member shall still be defined in a namespace scope if it is odr-used in the program and the namespace scope definition shall not contain an initializer.

在此上下文中,“odr-used”中的 odr 代表一个定义规则,意思是“其名称显示为潜在评估表达式”。 ([basic.def.odr])最后一句的意思是,如果你在类定义中声明static constexpr int foo = 0;,稍后你会在表达式中使用它,比如int x = MyClass::foo;,那么只有一个源文件需要有这样一行 constexpr int MyClass::foo; 在里面,所以链接器知道将其放入哪个目标文件。

关于c++ - 静态常量声明,变量的 constexpr 定义,有效的 C++?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43172652/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com