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 thetemplate<>
syntax. The same
is true when defining a member of an explicitly specialized member class. ...
Related Topics
C++ - Interval Tree Implementation
What Is a Nested Name Specifier
Do Static Members of a Class Occupy Memory If No Object of That Class Is Created
C++: How to Get Fprintf Results as a Std::String W/O Sprintf
In C/C++, Is Char* Arrayname[][] a Pointer to a Pointer to a Pointer or a Pointer to a Pointer
Move Constructor on Derived Object
C++ Inheritance and Member Function Pointers
Weird Msc 8.0 Error: "The Value of Esp Was Not Properly Saved Across a Function Call..."
Library Is Linked But Reference Is Undefined
How to Check If a Key Is Pressed on C++
Acquire/Release Semantics with 4 Threads
Undefined Reference to Google::Protobuf::Internal::Empty_String_[Abi:Cxx11]
Replace Multiple Spaces with One Space in a String
Safer But Easy-To-Use and Flexible C++ Alternative to Sscanf()