简体   繁体   中英

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

This is what I've got:

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

But I'd prefer to not use a function and instead just have a variable, like this:

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

What I want compiles, but when I try to use Foo::acgt_default_background_frequencies it gives the linker error "undefined reference to `Foo::acgt_default_background_frequencies'".

Is what I am trying to do possible? I think it is clearer to the reader of my header if I have the value inlined as a const than to hide it in the .cpp file and having a constant as opposed to a function also seems clearer. Isn't the point of constexpr to allow stuff like this? If it isn't possible, why not?

What you have in the second example is a declaration of a static data member which has an initializer, but you haven't provided a definition anywhere. If you make odr-use of that member, a definition will be required.

To provide a definition, add the following to your .cpp file

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

The declaration in the question works in C++14, but note that in C++11 you need an extra set of curly braces, eg

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

The relevant standardese from N3337 §9.4.2/3 [class.static.data]

... 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. ... The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM