Объект шаблона как статический член класса шаблона

Представьте себе следующий класс шаблона (сеттер и геттер для члена _t опущены):

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

Основная идея этой концепции заключается в том, что вместо использования нулевых указателей у меня есть статический элемент по умолчанию, который берет на себя эту роль, оставаясь при этом технически допустимым объектом; это может предотвратить некоторые проблемы с нулевыми указателями, одновременно делая код более подробным...

Я могу прекрасно создать экземпляр этого шаблона, но компоновщик выдает ошибку unresolved-external для статического объекта-члена NONE.

Я бы предположил, что при создании экземпляра шаблона строка static chain<T> NONE; фактически также будет определением, поскольку это фактически происходит в реализации, создающей экземпляр шаблона. Однако оказывается, что нет...

Мой вопрос: возможно ли вообще что-то подобное, и если да, то как, без явного определения элемента NONE перед каждым созданием шаблона?


person Mephane    schedule 23.06.2010    source источник
comment
Честно говоря, я не думаю, что это чище, чем использование нулевого указателя. Просто замените каждый &NONE на 0.   -  person GManNickG    schedule 24.06.2010


Ответы (2)


Вам все равно нужно определить это вне класса, как класс без шаблона. Как и в случае с классом, не являющимся шаблоном, вы только объявили NONE внутри определения класса, и вам все еще нужно его определить:

template<class T>
class chain
{
    // the same as your example
};

// Just add this
template <class T>
chain<T> chain<T>::NONE;
person R Samuel Klatchko    schedule 23.06.2010
comment
А, я вижу, вы можете определить статический элемент, оставаясь при этом шаблонным. Было бы хлопотно делать это для каждого экземпляра, но ваше решение идеально. - person Mephane; 24.06.2010

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

должно сработать

person Edward Strange    schedule 23.06.2010