Reputation: 2022
Imagine the following template class (setter and getter for the member _t
omitted):
template<class T>
class chain
{
public:
static chain<T> NONE;
chain()
: _next(&NONE)
{}
~chain() {}
chain<T>& getNext() const
{
return *_next;
}
void setNext(chain<T>* next)
{
if(next && next != this)
_next = next;
}
chain<T>& getLast() const
{
if (_next == &NONE)
return *this;
else
return _next->getLast();
}
private:
T _t;
chain<T>* _next;
};
The basic idea of this concept is, instead of using null-pointers, I have a static default element that takes in this role while still being a technically valid object; this could prevent some of the issues with null pointers while making the code more verbose at the same time...
I can instantiate this template just fine, but the linker gives an unresolved-external error on the static member object NONE
.
I would have assumed that when instantiating the template, the line static chain<T> NONE
; would effectively be a definition, too, as it actually happens within the implementation instantiating the template. However, it turns out not to be...
My question is: is something like possible at all, and if so, how, without explicitly defining the NONE
element before each and every template instantiation?
Upvotes: 1
Views: 625
Reputation: 76541
You still need to define that outside the class just like a non-template class. Just like in a non-template class, you have only declared NONE
inside the class definition and still need to define it:
template<class T>
class chain
{
// the same as your example
};
// Just add this
template <class T>
chain<T> chain<T>::NONE;
Upvotes: 3
Reputation: 40859
template < typename T >
chain<T> chain<T>::NONE;
should work
Upvotes: 2