Static Member Initialization for Specialized Template Class

How to initialize static members of two various types of template class

You need to do an explicit specialization which you do by writing an empty template declaration and replacing T in A<T> with the type you want.

template<> int A<int>::a = 5;
template<> int A<char>::a = 50;

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.

Resolving Definitions of Specialized Static Member Variables of Templated Classes

Is VC++ incorrect to reject the declaration/explicit specialization syntax for the static member variable of a templated class as previously stated, or is it an allowed but not mandatory diagnostic error?

Yes, this is a bug in VC++. It has apparently been fixed in Visual Studio 2019 version 16.5 Preview 2.


Does the removal of the declaration cause the program to be ill-formed?

Your quote from the standard seems to suggest that. Other people agree.


If it is ill formed without the declaration, how do I get VC++ to play nice with a well-defined program?

As a workaround, you can specialize the whole class and then define the member without the template<> syntax. See Amir Kirsh's answer to a similar question:
https://stackoverflow.com/a/58583521/758345

Alternatively, you could define and initialize your variable in your header and mark it as inline (since c++17):

template <> inline const std::string TemplatedClass::x = "string"; // .h file

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};

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.

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().

Hot to initialize static const member in specialized template code?

Just drop the template<> bit, and put the definition of the static data members in a .cpp file:

LookUp<uint8_t> Lbp<uint8_t>::_lookup{};
LookUp<uint16_t> Lbp<uint16_t>::_lookup{};

[Live example]

... and, since the type of _lookup is a class, you can leave out the {} as well; its default constructor will be called anyway. This might please VC++ if you're using a version which does not support uniform initialisation.

Why this is the proper way: template<> is used to introduce explicit specialisations. You're not introducing an explicit specialisation - you're defining a data member of an already defined explicit specialisation.

This is covered by C++11 14.7.3/5:

... Members of an explicitly specialized class template are
defined in the same manner as members of normal classes, and not using the template<> syntax. The same
is true when defining a member of an explicitly specialized member class. ...



Related Topics



Leave a reply



Submit