Static member initialization in a class template
Just define it in the header:
template <typename T>
struct S
{
static double something_relevant;
};
template <typename T>
double S<T>::something_relevant = 1.5;
Since it is part of a template, as with all templates the compiler will make sure it's only defined once.
Static member initialization in a template class
Maybe simpler
template<class T, class V>
bool fraction<T, V>::auto_reduce = true;
When you write
template<class T, class = typename enable_if<is_any_integral<T>::value>::type>
class fraction
you say that fraction
is a class with two type template paramenters; the std::enable_if
if part is useful to assign a default value to the second parameter (and to permit the enable/not enable SFINAE works) but fraction
is and remain a template class
with two parameters, you have to cite both and there is no need to repeat the enable/not enable/default part for second parameter initializing auto_reduce
.
C++ template class static members initialization
Add definition:
template<typename T1, typename T2>
T2 TemplateClass<T1, T2>::t2{};
Demo
Class Template Static Member Initialized Twice
This code looks correct to me: count_default
and count_static_assign
have constant expressions as initializers, so they must be initialized before any dynamic initialization happens. STATIC_TYPE
is dynamic initialization.
OP reports that changing std::numeric_limits<Key>::min()
to 0
fixes the behaviour of the program, so I would conjecture that the compiler has a bug that it does not consider the constexpr
function std::numeric_limits<Key>::min()
to be a constant expression.
To work around this you could try some other way of coming up with a constant initializer for count_static_assign
, e.g. a constexpr function that you write yourself, or a specialization for each type that you do use.
Template class's static variable initialization, c++
Compiler will remove duplicate template instantiations on its own. If you turn your template class into regular one, then its your duty to make sure only one definition of static variable exists (otherwise linker error will appear). Also remember that static data members are not shared between instatiations of templates for different types. With c++11 you can control instatiations on your own using extern templates: using extern template (C++11).
As for the point of instatiation for static members:
14.6.4.1 Point of instantiation [temp.point]
1 For a function template specialization, a member function template specialization, or a specialization for a
member function or static data member of a class template, if the specialization is implicitly instantiated
because it is referenced from within another template specialization and the context from which it is referenced
depends on a template parameter, the point of instantiation of the specialization is the point of
instantiation of the enclosing specialization. Otherwise, the point of instantiation for such a specialization
immediately follows the namespace scope declaration or definition that refers to the specialization.
so point of instatiation should be ie. right after main() if you use your type for the first time inside main().
static member variable in class template
This is perfectly fine, in this case of defining it in the header the compiler will insure there is only one instance, if we see the draft C++ standard section 3.2
One definition rule paragraph 6 says(emphasis mine):
There can be more than one definition of a class type (Clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (Clause 14), non-static function template (14.5.6), static data member of a class template (14.5.1.3), member function
we can then go to section 14.5.1.3
Static data members of class templates paragraph 1 says:
A definition for a static data member may be provided in a namespace scope enclosing the definition of the static member’s class template.
and provides the following example:
template<class T> class X {
static T s;
};
template<class T> T X<T>::s = 0;
Class template static data-member definition/declaration/initialization
You hit a bug in MSVC. It has apparently been fixed in Visual Studio 2019 version 16.5 Preview 2.
As an alternative workaround, you could leave your definitions in the header and mark them as inline (since c++17):
template<>
inline std::array<float,1U> A<1U>::a1{1.};
template<>
inline std::array<float,2U> A<2U>::a1{0.3,0.3};
Related Topics
Purpose of Returning by Const Value
Reason to Pass a Pointer by Reference in C++
Where Does Visual Studio Look For C++ Header Files
Right Way to Split an Std::String into a Vector≪String≫
Boolean Expression (Grammar) Parser in C++
Is Ncurses Available For Windows
Visual C++ Equivalent of Gcc'S _Attribute_ ((_Packed_))
What Is the Windows Equivalent For En_Us.Utf-8 Locale
Convert String to Variable Name or Variable Type
Error: Passing Xxx as 'This' Argument of Xxx Discards Qualifiers
Std::Endl Is of Unknown Type When Overloading Operator≪≪