C++类是否可以在头文件中包含内联初始化的静态const std :: array?

JDi*_*teo 5 c++ c++11

这就是我所拥有的:

struct Foo
{
   static std::array<double, 4> acgt_default_background_frequencies() { return {0.281774, 0.222020, 0.228876, 0.267330}; }
};
Run Code Online (Sandbox Code Playgroud)

但我宁愿不使用函数而只是有一个变量,如下所示:

struct Foo
{
   static constexpr std::array<double, 4> acgt_default_background_frequencies = {0.281774, 0.222020, 0.228876, 0.267330};
};
Run Code Online (Sandbox Code Playgroud)

我想要编译,但当我尝试使用 Foo::acgt_default_background_frequencies它时,链接器错误"未定义引用`Foo :: acgt_default_background_frequencies'".

我正在尝试做什么?我认为我的标题的读者更清楚,如果我将值内联为const而不是将其隐藏在.cpp文件中并且具有常量而不是函数也看起来更清晰.constexpr是不是允许这样的东西?如果不可能,为什么不呢?

Pra*_*ian 6

您在第二个示例中所拥有的是具有初始值设定项的数据成员的声明static,但您没有在任何地方提供定义.如果您对该成员进行odr使用,则需要定义.

要提供定义,请将以下内容添加到.cpp文件中

constexpr std::array<double, 4> Foo::acgt_default_background_frequencies;
Run Code Online (Sandbox Code Playgroud)

问题中的声明适用于C++ 14,但请注意,在C++ 11中,您需要一组额外的花括号,例如

struct Foo
{
  static constexpr std::array<double, AlphabetSize> acgt_default_background_frequencies = {{0.281774, 0.222020, 0.228876, 0.267330}};
};
Run Code Online (Sandbox Code Playgroud)

N3337§9.4.2/ 3 [class.static.data]的相关标准

... static可以使用说明constexpr符在类定义中声明文字类型的数据成员; 如果是这样,它的声明应指定一个大括号或等于初始化器,其中作为赋值表达式的每个initializer子句都是一个常量表达式....如果程序中使用了odr-used(3.2),并且命名空间作用域定义不包含初始化程序,则该成员仍应在命名空间作用域中定义.