Static Member Initialization in a Class Template

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



Leave a reply



Submit