предположим, что мы имеем класс, как это:Реализация дорогой с ++ итератора
#include <cstdio>
struct A{
struct it{
it(int i) : i(i){
printf("c-tor %d\n", i);
}
it &operator++(){
i++;
return *this;
}
int operator*(){
return i;
}
bool operator!=(const it &ot){
return i != ot.i;
}
int i;
};
it begin() const{
return it(0);
}
it end() const{
return it(10);
}
it end_it = it(10);
const it &xend() const{
return end_it;
}
};
int main(){
A a;
printf("for\n");
for(A::it i = a.begin(); i != a.end(); ++i)
printf("%d\n", *i);
printf("c++11 for\n");
for(int j : a)
printf("%d\n", j);
printf("memoize\n");
A::it my_end = a.end();
for(A::it i = a.begin(); i != my_end; ++i)
printf("%d\n", *i);
printf("ref\n");
for(A::it i = a.begin(); i != a.xend(); ++i)
printf("%d\n", *i);
}
EDIT: итератор Неконстантный итератор. В этом примере очень просто, и это не очевидно.
Когда мы делаем первый цикл, новый итератор конца построен для каждой итерации цикла.
Если мы назначим класс из end() переменной (например, memoize), такой проблемы нет.
C++ 11, возможно, делает то же самое.
Наконец, end()
может возвращать ссылку, но код намного сложнее и, вероятно, будет создавать проблемы в будущем.
Что такое правильный способ реализации дорогостоящего итератора?
Если вы не модифицируете контейнер, вы можете вызвать 'end()' только один раз перед входом в цикл. См. Также [Sutter] (http://herbsutter.com/2013/05/13/gotw-2-solution-temporary-objects/) –
Да, это константный итератор, я отредактирую вопрос. – Nick
Устойчивость итератора мало что может сделать, если вы измените контейнер (а не содержимое контейнера) – Yakk