c++类可以在头文件中包含内联初始化的静态const std::数组吗?

Can a C++ class contain a static const std::array initialized inline in a header file?

本文关键字:const 静态 std 初始化 数组 包含内 文件 c++      更新时间:2023-10-16

这是我得到的:

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

但是我更喜欢不使用函数,而是有一个变量,像这样:

struct Foo
{
   static constexpr std::array<double, 4> acgt_default_background_frequencies = {0.281774, 0.222020, 0.228876, 0.267330};
};

我想编译的,但是当我尝试使用Foo::acgt_default_background_frequencies时,它会给链接器错误"对' Foo::acgt_default_background_frequencies'的未定义引用"。

我想做的是可能的吗?我认为,如果我将值内联为const,而不是将其隐藏在.cpp文件中,那么对于我的头的读者来说,这是更清晰的,并且具有常数而不是函数也似乎更清晰。警员允许这样的事情发生不是很重要吗?如果不可能,为什么不呢?

在第二个示例中,您拥有的是具有初始化式的static数据成员的声明,但是您没有在任何地方提供定义。如果对该成员使用odr-use,则需要定义。

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

constexpr std::array<double, 4> Foo::acgt_default_background_frequencies;

问题中的声明在c++ 14中有效,但注意在c++ 11中你需要额外的一组花括号,例如

struct Foo
{
  static constexpr std::array<double, AlphabetSize> acgt_default_background_frequencies = {{0.281774, 0.222020, 0.228876, 0.267330}};
};

N3337 §9.4.2/3/3 [class.static.data]

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