Как я применяю принцип DRY к итераторам в C++? (итератор, const_iterator, reverse_iterator, const_reverse_iterator)

Можно также пойти с Приложением. Событие ThreadException.

, Как только я разрабатывал приложение.NET, работающее в COM, основывал приложение; это событие было очень полезным как AppDomain. CurrentDomain. UnhandledException не работал в этом случае.

5
задан exscape 21 November 2009 в 20:17
поделиться

5 ответов

Иногда общее применение так называемого правила DRY ( Don't Repeat Yourself , для тех, кто не знаком) - не лучший подход. Особенно, если вы новичок в языке (C ++ и итераторы) и самом ООП (методологии), мало пользы от попытки минимизировать объем кода, который вам нужно написать прямо сейчас .

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

3
ответ дан 14 December 2019 в 08:53
поделиться

Сделайте итератор производным от const_iterator, а не наоборот. Используйте const_cast надлежащим образом (как деталь реализации, не раскрываемую для пользователей). Это очень хорошо работает в простых случаях и моделях, в которых «итераторы являются const_iterators» напрямую.

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

struct Container {
#define G(This) \
This& operator++() { ++_internal_member; return *this; } \
This operator++(int) { This copy (*this); ++*this; return copy; }

  struct iterator {
    G(iterator)
  };
  struct const_iterator {
    G(const_iterator)
    const_iterator(iterator); // and other const_iterator specific code
  };
#undef G
};

Макрос имеет ограниченную / локализованную область видимости, и, конечно же, используйте его только в том случае, если он действительно помогает вам - если это приводит к меньшему читаемый код для вас, введите его явно.

А насчет обратных итераторов: вы можете использовать std :: reverse_iterator , чтобы обернуть ваш "нормальный" итераторы во многих случаях вместо их перезаписи.

struct Container {
  struct iterator {/*...*/};
  struct const_iterator {/*...*/};

  typedef std::reverse_iterator<iterator> reverse_iterator;
  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
};
1
ответ дан 14 December 2019 в 08:53
поделиться

На самом деле это очень просто.

Прежде всего, взгляните на библиотеку Boost.Iterator .

Во-вторых: вам нужно объявить базовый класс (в примере хорошо объяснено, как действовать), который будет похож на этот.

template <class Value>
class BaseIterator: boost::iterator_adaptor< ... > {};

Вы реализуете операции для перемещения указателя туда. Обратите внимание: поскольку это адаптация к уже существующему итератору, вы можете реализовать его всего несколькими штрихами. Это действительно впечатляет.

В-третьих, вы просто набираете его с константной и неконстантной версиями:

3
ответ дан 14 December 2019 в 08:53
поделиться

LinkedList :: iterator i = const_list.begin () Как выглядит ваш метод begin? Изучая STL, вы можете увидеть, что контейнеры определяют два таких метода со следующими сигнатурами:

const_iterator begin() const;
iterator begin();

У вас не должно возникнуть проблем с получением итератора из объекта, квалифицированного как const. Я не думаю, что здесь применяется DRY.

0
ответ дан 14 December 2019 в 08:53
поделиться

Когда-то я использовал следующий подход:

  1. создать шаблонный класс common_iterator
  2. добавить typedefs для «iterator» и «const_iterator»
  3. добавить в «common_iterator» конструктор, принимающий » iterator "type

Для" итератора "дополнительный конструктор заменит конструктор копирования по умолчанию, в моем случае он был эквивалентен конструктору копирования по умолчанию.

Для" const_iterator "это будет дополнительный конструктор, который позволяет построить" const_iterator " из "итератора"

0
ответ дан 14 December 2019 в 08:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: