Consider the following construct:
//! Templated singleton.
/*!
Template wrapper enforcing the singleton behavior.
*/
template <class T>
class TSingleton
{
private:
//! Singleton instance pointer.
static T* instance;
//! private constructor.
TSingleton() { }
//! private empty copy constructor.
TSingleton(const TSingleton<T>& sourceObject) {}
public:
//! Static singleton instance getter.
static T* GetInstance()
{
if (instance == 0)
instance = new T();
return instance;
}
};
template <class T> T* TSingleton<T>::instance = 0;
This template class and the definition of the static instance are written in the same header file. For a non-template class, this causes a link-time error due to multiple symbols being defined for the instance static member. It seems intuitive for this to happen with templates as well, thus one must separate the definition and put it in a .cpp file. But templates are usually declared and defined in header-like files. What is it that allows this syntax to be valid and functional for template classes?
There a wikipedia link on this, but it does not provide a clear explanation on what happens in case of template classes.
Yes, It can be declared. It will be considered as a global static variable. It will limit its scope within that file in which that header file has been included.
To have all the information available, current compilers tend to require that a template must be fully defined whenever it is used. That includes all of its member functions and all template functions called from those. Consequently, template writers tend to place template definition in header files.
Templates are a feature of the C++ programming language that allows functions and classes to operate with generic types. This allows a function or class to work on many different data types without being rewritten for each one.
The static member functions are special functions used to access the static data members or other static member functions. A member function is defined using the static keyword. A static member function shares the single copy of the member function to any number of the class' objects.
This works because [basic.def.odr]/5
explicitly allowed templates to be duplicated:
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 of a class template (14.5.1.1), or template specialization for which some template parameters are not specified (14.7, 14.5.5) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. ...
The requirements are quite lengthy, so I won't duplicate them here, but essentially they state that each duplicate definition must be identical (otherwise the program has undefined behaviour).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With