Question

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?

Was it helpful?

Solution

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;

OTHER TIPS

template < typename T >
chain<T> chain<T>::NONE;

should work

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top