Experimentally, I know how to declare/initialize/define static data member of various kinds (mainly by reading the compiler diagnosis) yet I realize that I don't really understand the rules behind these mechanics and, noticibly the difference between const and constexpr static data member of template class.
Let say I have the following files.
TemplateODR.hpp
template <typename T>
struct TData {
static T m_Value;
static constexpr T m_kValue = T(3.14);
};
TemplateDoubleSpecialization.hpp
template <>
double TData<double>::m_Value;
// cannot gives a different specialization for the constexpr
// KO: template<> double TData<double>::m_kValue = 2.72;
TemplateDoubleSpecialization.cpp
template <>
double TData<double>::m_Value = 3.14;
TestODRUse#N.cpp
void TestODRUse#N() {
std::cout << TData<double>::m_Value << '\n';
std::cout << TData<double>::m_kValue << '\n';
}
main.cpp
int main() {
TestODRUse1();
TestODRUse2(); // testing for ODR violations
}
Other trivial header files and #include directives required as glue between the different files are omitted on purpose for clarity sake.
The full example is available here.
It seems that constexpr static data is a bit peculiar for template: a const static data member can be redefined for each specialization but the same does not apply to constexpr static data. We must resort, for instance, to
Specialize static constexpr data member. Why isn't it possible to manage a const and a constexpr static data member in the same way?