В Herb Sutter When Is a Container Not a Container?
он показывает пример ввода указателя в контейнер:
// Example 1: Is this code valid? safe? good?
//
vector<char> v;
// ...
char* p = &v[0];
// ... do something with *p ...
Затем следует за ним "улучшение":
// Example 1(b): An improvement
// (when it possible)
//
vector<char> v;
// ...
vector<char>::iterator i = v.begin();
// ... do something with *i ...
Но не дает убедительного аргумента:
В общем, это не плохой ориентир, чтобы вместо этого использовать итераторы указателей, когда вы хотите указать на объект, который внутри контейнер. В конце концов, итераторы недействительны в большинстве случаев временами и теми же способами, что и указатели, и одна из причин того, что итераторы существует, чтобы обеспечить способ "указывать" на содержащийся объект. Итак, если вы имеют выбор, предпочитают использовать итераторы в контейнерах.
К сожалению, вы не всегда можете получить тот же эффект с итераторами что вы можете с указателями в контейнер. Есть два основных потенциальные недостатки метода итератора, и когда мы применяем должны продолжать использовать указатели:
Вы не всегда можете удобно использовать итератор, где вы можете использовать указатель. (См. Пример ниже.)
Использование итераторов может привести к лишним затратам на занятие места и производительности, в случаях, когда итератором является объект, а не только лысый указатель.
В случае вектора итератор является просто случайным идентификатором. Для всех целей и целей это тонкая оболочка над указателем. Одна реализация даже подтверждает это:
// This iterator adapter is 'normal' in the sense that it does not
// change the semantics of any of the operators of its iterator
// parameter. Its primary purpose is to convert an iterator that is
// not a class, e.g. a pointer, into an iterator that is a class.
// The _Container parameter exists solely so that different containers
// using this template can instantiate different types, even if the
// _Iterator parameter is the same.
Кроме того, реализация сохраняет значение члена типа _Iterator
, которое равно pointer
или T*
. Другими словами, просто указатель. Кроме того, difference_type
для такого типа std::ptrdiff_t
, а определенные операции - только тонкие обертки (т.е. operator++
- ++_pointer
, operator*
- *_pointer
) и т.д.
После аргумента Sutter этот класс итератора не дает преимуществ по сравнению с указателями, а только недостатками. Правильно ли я?