Общая инициализация итератора / указателя - PullRequest
1 голос
/ 11 ноября 2011

У меня есть класс C ++ Finder, который хранит местоположение в контейнерах плюс некоторые дополнительные данные.Такие контейнеры имеют тип std::string, но также char * или MyString.Скажем, класс выглядит следующим образом (Iterator<TContainer>::Type - это признак / мета-функция, которая возвращает тип итератора для данного контейнера):

template <typename TContainer>
class Finder
{
public:
  typedef typename Iterator<TContainer>::Type TIterator;
  TIterator iterator;

  // Initialization of iterator: How to do it generically?

  // Finder {}                       // problem with pointers!
  // Finder() : iterator(0) {}       // problem with iterators!
};

Теперь главная проблема заключается в том, как инициализировать итератор, который может бытьуказатель или итератор.Если бы я только хотел поддерживать свои собственные контейнеры, то я мог бы просто реализовать конструктор, который принимает nullptr_t после идиома nullptr .Однако, так как я хочу поддерживать указатели, мои собственные итераторы и STL, я немного не в этом разбираюсь.

Лучшее, что я могу себе представить, это написать getNil<>() функция, например код ниже.Однако теперь возникает как минимум три вопроса:

  1. Является ли это наилучшим способом достижения моей цели?

  2. Как определить, является ли типSTL итератор?Возможно, мне понадобится #if s и индивидуальный код для каждой версии компилятора / STL.

  3. Возможно ли вообще получить nil итераторв STL?Определен ли результат x-y в std::vector<int> x, y; int x = x-y; вообще?

Код:

// Forward declaration.
template <typename T>
T getNil<T>();

template <typename TValue> TValue * getNil<TValue *>()
{ return NULL; }

template <typename TValue> TValue * const getNil<TValue * const>()
{ return NULL; }

template <> TValue * const getNil<MyIterator>()
{ return MyIterator(nullptr); }  // nullptr from above idiom

template <> TStlIterator
boost::enable_if<
    MagicallyDetermineIfIsStlIterator<TStlIterator>::value,
    TStlIterator>
getNil<TStlIterator>()
{ return MyIterator(nullptr); }  // nullptr from above idiom

1 Ответ

3 голосов
/ 11 ноября 2011
Finder() : iterator() { }

Должен сделать свое дело. Отсутствие аргумента для члена в списке инициализации вызовет конструктор по умолчанию для типа, у которого он есть, и инициализирует нулями POD-типы, включая указатели (и произойдет сбой, если тип не имеет конструктора по умолчанию, но это вряд ли ваш сценарий).

...