2016-06-02 6 views
3

Я знаю, что std::forward_list<T>::iterator не имеет оператора составного присвоения (operator+=). Но почему?Почему не пересылать итератору есть оператор присваивания?

Я спрашиваю это по трем причинам:

  1. бы не этот оператор продвигает «вперед» итератор как operator++()?
  2. Нет ли вспомогательной функции std::advance(), что делает то же самое?
  3. Я реализую свой собственный список переходов (для обучения), и я хочу знать, что не так с operator+=().
+1

Будет ли downvoter объяснить, что случилось с этим вопросом? – Laith

ответ

9

Использование:

std::advance(it, n); 

(Заявлен в <iterator>.)

Дело в том, что операторы составного присваивания обеспечиваются только тогда, когда операция имеет O (1) затрат. Поскольку приращение прямого итератора имеет линейную стоимость, лучше сделать это явным.

Если вы хотите новое значение, что это результат многократных приращений, используйте:

auto it2 = std::next(it1, n); 
+3

Я ожидал, что кто-то ответит на этот вопрос, «потому что стандарт говорит так:« Я рад (для OP), что вы этого не сделали. +1. – Borgleader

+1

Является ли 'it + = 2' действительно менее явным, чем' advance (it, 2) '? – Barry

+0

@ Barry: Ну, это было сочтено комитетом. Дело не в том, что '+ = 2' непонятно, но люди не чувствовали себя комфортно, что это может быть дорогостоящая операция. Итераторы - это обобщение указателей, и когда вы видите '+ = 2', вы считаете арифметику указателя в первую очередь. –

5

Но я не знаю, почему?

Ну, итератор вперед может быть продвинут вперед только по одной единице за раз. += обычно используется для одновременной передачи нескольких единиц.

не будет ли этот оператор продвигать «вперед» итератор, как operator++()?

Это было бы, но вы могли бы использовать его как iterator += 10, который оставил бы вас поверить, что он будет продвигать 10 мест сразу. Вместо этого это должно быть 10 отдельных вызовов ++.

Не существует вспомогательной функции std :: advance(), которая делает то же самое?

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

Я реализую свой собственный вперед список (для обучения), и я хочу знать, что случилось с оператором + =()

Вашего итератор должен соответствовать стандартному определению переднего итератора.

+0

Дополнительная проблема: что, если вы добавите отрицательное число? –

+0

@Revolver_Ocelot Ну, что можно решить, используя неподписанный тип для параметра функции;) К сожалению, std :: advance также позволяет это. – NathanOliver

1

Но я не знаю почему?

Существует определенный контракт, согласно которому итераторы разных категорий должны следовать.Описание можно найти here Вы можете увидеть, что контракт на ForwardIterator категории, где std::forward_list<T>::iterator принадлежит, и нет r += n операции, которая является для RandomAccessIterator