2015-09-22 4 views
0

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

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

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

Я действительно не могу понять, что делать, любые идеи?

Поняв ответ, заголовок вводит в заблуждение, извините!

Спасибо,

Йохан

+3

Это правильное поведение –

+0

@PaoloM Прежде всего, я начинающий C++, поэтому позвольте мне только извиниться за это заранее. Какое правильное поведение? Что делает мой код или что говорит сайт? Они делают разные вещи, как указано в вопросе. –

+0

Правильное поведение заключается в том, что 'operator ++' вызывается до 'operator *'. Это стандартный приоритет оператора. –

ответ

1

Из ссылке, которую Вы предоставили, *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)++; 

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

+0

Спасибо за ваш ответ, я начинаю чувствовать себя немым ... Как мне реализовать, чтобы '* i ++' приводил приведенное вами поведение? Я понимаю, что я могу указать приоритет операторов в инструкции, но как мне сделать это по умолчанию? –

+0

@JohanS, какое поведение? Один в начале ответа? – lisyarus

+0

Да, что поведение –

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++, но вам также не нужно.

+0

Хорошо, я получил это сейчас, спасибо! –

Смежные вопросы