Proper initialization of static constexpr array in class template?

前端 未结 2 1197
无人共我
无人共我 2021-01-07 20:12

Static class members in C++ have caused a little confusion for me due to the standard\'s verbiage:

9.4.2 Static data members [class.sta

2条回答
  •  臣服心动
    2021-01-07 20:26

    I think you want 9.4.2p3:

    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 (5.19). 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 definition of a template static data member is a template-declaration (14p1). The example given in 14.5.1.3p1 is:

    template class X {
      static T s;
    };
    template T X::s = 0;
    

    However, as above a constexpr static or const static member whose in-class declaration specifies an initializer should not have an initializer in its namespace scope definition, so the syntax becomes:

    template class X {
      const static T s = 0;
    };
    template T X::s;
    

    The difference with the non-array (i.e. integral or enumeration) static constexpr data member is that its use in lvalue-to-rvalue conversion is not odr-use; you would only need to define it if taking its address or forming a const reference to it.

提交回复
热议问题