C++ 3d.Комментарии


Обратные итераторы


Это приводит к тому, что * возвращает значение *(current-1)...

Да, по смыслу именно так:

24.4.1.3.3 operator* [lib.reverse.iter.op.star]

reference operator*() const;

  1. Действия:

    Iterator tmp = current; return *--tmp;

Т.е. каждый раз, когда вы применяете разыменование обратного итератора, происходит создание временного итератора, его декремент и разыменование. Не многовато ли, для такой простой и часто используемой (как правило, в цикле для каждого элемента) операции? Д-р Страуструп пишет по этому поводу следующее:

I don't think anyone would use a reverse iterator if an iterator was an alternative, but then you never know what people might know. When you actually need to go through a sequence in reverse order a reverse iterator is often quite efficient compared to alternatives. Finally, there may not be any overhead because where the iterator is a vector the temporary isn't hard to optimize into a register use. One should measure before worrying too much about overhead.

Я не думаю, что бы кто-то использовал обратный итератор там, где можно использовать обычный, но мы никогда не можем знать, что думают другие люди. Когда вам действительно нужно пройти последовательность в обратном порядке, обратный итератор является вполне приемлемой альтернативой. В принципе, иногда можно вообще избежать накладных расходов, например в случае обратного прохода по вектору, когда временная переменная-итератор без труда размещается в регистре. В любом случае, не стоит чрезмерно беспокоиться о производительности не проведя реальных измерений.

Вместе с тем, обратный итератор все-таки несет в себе ненужные накладные расходы, и для обратного прохода по последовательности лучше использовать обычный итератор с явным (пре)декрементом.

И раз уж речь зашла о реальных измерениях, давайте их произведем. #include <stdio.h> #include <stdlib.h> #include <time.h> #include <list>

long Count, Var;

typedef std::list<int> list_type; list_type lst;

void f1() { for (list_type::reverse_iterator ri=lst.rbegin(), rend=lst.rend(); ri!=rend; ++ri) Var+=*ri; }




Начало  Назад  Вперед



Книжный магазин