Как переопределить * i ++ для c ++ пользовательского итератора?

Это меня очень смущает, я использую собственный итератор и читаю здесь: http://en.cppreference.com/w/cpp/concept/InputIterator, что поведение *iter++ сначала следует использовать оператор разыменования, а затем увеличить возвращаемое значение (которое копируется) на 1.

В моем собственном итераторе переопределены оба operator* а также operator++(int v), проблема в том, что operator++(int v) называется раньше operator* когда я выполню *iter++, что является правильным поведением, но не для того, что я хочу сделать (я полагаю?).

Если вы прочтете ссылку, вы увидите, что в таблице в последней строке сказано, что если вы выполните *iter++Ваша реализация должна сначала разыменовывать, а затем увеличивать результат, что не является поведением по умолчанию.

Кажется, я не знаю, что делать, есть идеи?

После понимания ответа название вводит в заблуждение, извините!

Спасибо,

Johan

0

Решение

По ссылке, которую вы предоставили, *i++ эквивалентно:

value_type x = *i; // (1)
++i;               // (2)
return x;          // (3)

То есть,

  1. Разыщите итератор i и сохранить его в x
  2. Увеличить итератор
  3. Вернуть значение x полученный разыменованием до увеличивая итератор.

Это можно использовать в коде шаблона, который принимает входные итераторы, например:

template <typename InputIterator, typename T>
InputIterator drop_until (InputIterator i, T const & x)
{
while (*i++ != x);
return i;
}

Реализация этого поведения обычно выглядит

struct my_iterator
{
// ...

value_type operator * ()
{
// return the value that this operator is pointing to
}

my_iterator operator ++ (int)
{
my_iterator copy = *this;
// increment *this iterator
return copy;
}

// ...
};

Это работает, потому что i++, который вызывает operator++(int), возвращает предыдущее значение итератора, которое затем разыменовывается, в то время как i сам увеличивается.

Чтобы увеличить значение разыменования, вы должны вручную указать приоритет операторов:

(*i)++;

Так как в стандарте C ++ определяется приоритет операторов, вы не можете добиться такого поведения для выражения *i++, или же i я думаю, перестал бы быть итератором.

1

Другие решения

Если вы прочтете ссылку, то увидите, что в таблице в последней строке сказано, что если вы выполните * iter ++, ваша реализация должна сначала разыменовать, а затем увеличить результат

Порядок операций не имеет отношения к результату. На сайте не говорится, что операторы должны вызываться в таком порядке, просто побочные эффекты должны быть эквивалентны. Пример на сайте упрощен. Следование имеет эквивалентные побочные эффекты, но также имеет тот же порядок операций, что и реальная реализация этих двух операторов при вызове. *iter++:

const It it_copy = i; // copying the iterator is part of post increment
++i; // increment is called first
value_type value = *it_copy; // dereference second
return value;

Результат будет таким же.

Вы не можете получить заказ, указанный в этой таблице, если вы позвоните *iter++ но вам тоже не нужно.

1

По вопросам рекламы [email protected]