Это меня очень смущает, я использую собственный итератор и читаю здесь: http://en.cppreference.com/w/cpp/concept/InputIterator, что поведение *iter++
сначала следует использовать оператор разыменования, а затем увеличить возвращаемое значение (которое копируется) на 1.
В моем собственном итераторе переопределены оба operator*
а также operator++(int v)
, проблема в том, что operator++(int v)
называется раньше operator*
когда я выполню *iter++
, что является правильным поведением, но не для того, что я хочу сделать (я полагаю?).
Если вы прочтете ссылку, вы увидите, что в таблице в последней строке сказано, что если вы выполните *iter++
Ваша реализация должна сначала разыменовывать, а затем увеличивать результат, что не является поведением по умолчанию.
Кажется, я не знаю, что делать, есть идеи?
После понимания ответа название вводит в заблуждение, извините!
Спасибо,
Johan
По ссылке, которую вы предоставили, *i++
эквивалентно:
value_type x = *i; // (1)
++i; // (2)
return x; // (3)
То есть,
i
и сохранить его в x
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
я думаю, перестал бы быть итератором.
Если вы прочтете ссылку, то увидите, что в таблице в последней строке сказано, что если вы выполните * 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++
но вам тоже не нужно.