Самый легкий способ сделать циклический итератор (шарлатан)?

Средства проверки надежности пароля, и если у Вас есть time+resources (ее выровненный по ширине, только если Вы проверяете на больше, чем несколько паролей) используют Таблицы Радуги.

13
задан Reinstate Monica 21 August 2015 в 03:39
поделиться

3 ответа

boost::iterator adaptor is the way to go, take my word for it ;)

That being said I want to point out a few pitfalls. I don't think I can edit an existing answer, so bear with me.

Given that your base iterator is going to be a vector you need to be careful which core interface functions you need to implement. If you want your cycle_iterator to be a random access iterator you need all of the following:

increment() 
decrement()
advance(n)
distance_to(j)

Now distance_to(j) is a somewhat funny concept for a cycle_iterator and its semantics can get you in all kind of trouble. This can be avoided by restricting the iterator category of the adapted iterator to either forward or bidirectional. Like this:

template <class BaseIterator>
class cycle_iterator
  : public boost::iterator_adaptor<
        cycle_iterator                  // Derived
      , BaseIterator                    // Base
      , boost::use_default              // Value
      , boost::forward_traversal_tag    // CategoryOrTraversal
    >
{ ... };

In this case you only need to implement increment:

void increment()
{
  if (++this->base_reference() == this->m_itEnd)
  {
    this->base_reference() = this->m_itBegin;
  }
}

For a bidirectional you also need decrement:

void decrement()
{
  if (this->base_reference() == this->m_itBegin)
  {
    this->base_reference() = this->m_itEnd;
  }
  --this->base_reference();
}

Disclaimer: I did not run this through a compiler, so I am ready to be embarrassed.

8
ответ дан 1 December 2019 в 21:25
поделиться

Создайте свою собственную коллекцию из std :: vector и предоставьте собственную реализацию итератора, которая переопределяет операторы увеличения и уменьшения.

В Интернете есть множество учебных пособий. Например, посмотрите это сообщение в блоге

-4
ответ дан 1 December 2019 в 21:25
поделиться

Хорошо, теперь ваша проблема яснее: -)

Взгляните на адаптер boost :: iterator_facade и boost :: iterator. Они реализуют полный интерфейс итератора и ваш cycle_iterator только для реализации нескольких методов, таких как increment (), Decment ():

template<class IteratorBase>
class cycle_iterator 
     : public boost::iterator_adaptor< 
          cycle_iterator,     // the derived class overriding iterator behavior
          IteratorBase,       // the base class providing default behavior
          boost::use_default, // iterator value type, will be IteratorBase::value_type
          std::forward_iterator_tag, // iterator category
          boost::use_default  // iterator reference type
       > 
{
  private:
     IteratorBase m_itBegin;
     IteratorBase m_itEnd;

  public:
     cycle_iterator( IteratorBase itBegin, IteratorBase itEnd ) 
       : iterator_adaptor_(itBegin), m_itBegin(itBegin), m_itEnd(itEnd)
     {}

     void increment() {
        /* Increment the base reference pointer. */
        ++base_reference();

        /* Check if past-the-end element is reached and bring back the base reference to the beginning. */
        if(base_reference() == m_itEnd)
            base_reference() = m_itBegin;
     }

     // implement decrement() and advance() if necessary
  };

Это, вероятно, не компилируется, но должно помочь вам начать работу.

Правка:

boost :: iterator_adaptor реализует полный интерфейс итератора с точки зрения нескольких функций. Он предоставляет реализации по умолчанию для increment () , декремента () , advance () , distance_to () , equal_to ( ) и dereference () с использованием базового итератора, переданного базовому классу iterator_adaptor .

Если вам нужен только прямой итератор, только метод increment () должен быть реализован для циклического перехода после достижения конечного итератора. Циклический итератор может быть двунаправленным, если аналогичным образом реализовать декремент () . Если IteratorBase сам является итератором с произвольным доступом, итератор цикла также может быть с произвольным доступом, и методы advance и distance_to должны быть реализованы с использованием операций по модулю.

итератор цикла также может иметь произвольный доступ, и методы advance и distance_to должны быть реализованы с использованием операций по модулю.

итератор цикла также может иметь произвольный доступ, и методы advance и distance_to должны быть реализованы с использованием операций по модулю.

22
ответ дан 1 December 2019 в 21:25
поделиться
Другие вопросы по тегам:

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