1

Why I can specialize a static method A<int>::func() and a static nonconst variable A<int>::flag, but cannot specialize a static const variable A<int>::const_flag?

template <class T>
struct A {
  static void func() {};
  static bool iso_error = true; // ISO C++ forbids in-class initialization of non-const static member 'A<int>::iso_error'
  static bool flag;
  const static bool const_flag = true;
};
template <class T>
bool A<T>::flag = true; // works fine


template <>
void A<int>::func() {}; // works fine
template <>
bool A<int>::flag = false; // works fine
template <>
const bool A<int>::const_flag = false; // duplicate initialization of 'A<int>::const_flag'
  • *ISO C++ forbids in-class initialization of non-const static member 'A::iso_error'* is allowed if it is `inline`, like `static inline bool iso_error = true;` – Eljay Nov 09 '22 at 14:39
  • Afaict the dupe does not answer this question. The dupe focuses on _constexpr_ static data members, which have the restriction that they _must_ be initialized at its declaration. The case of this question is, however, subtly different: the `const_flag` member is particularly [a non-volatile non-inline const static data member is of integral or enumeration type](https://timsong-cpp.github.io/cppwp/n4868/class.static.data#4), leveraging, in the primary template of `A`, that it _may_ specify an initializer at its declaration. ... – dfrib Nov 09 '22 at 15:16
  • The key here is rather that _if_ the common _declaration_ of the static data member in the primary class template contains an initializer, than [_no definition_ which refers to the entity previously _declared_ may contain an initializer](https://timsong-cpp.github.io/cppwp/n4868/class.static.data#4.sentence-2). As OP has not specialized the class template `A` itself over `int`, the _declaration_ of the static data member `const_flag` will refer to that of the primary template, even for specializations for which an explicit specialization exists for the _definition_ of the static data member. – dfrib Nov 09 '22 at 15:20
  • As a contradiction in the context of OP's example, explicit specializations of static data members of class templates [are definitions only if they include an initializer](https://timsong-cpp.github.io/cppwp/n4868/temp.expl.spec#15), otherwise they're declarations. Thus, to tweak OP's example whilst upholding the original intent, the primary class template shall declare but not initialize the `const_flag` member, and leave initialization to a primary template _definition_ of the member, and explicit specializations overrides this primary (static data member of class template) definition. – dfrib Nov 09 '22 at 15:36
  • [DEMO](https://wandbox.org/permlink/sppFeMh3MyWqs1Me). – dfrib Nov 09 '22 at 15:36

0 Answers0