Здравствуйте, korzhik, Вы писали:
K>Теперь отвечаю: вот так vectorObj + 7 делать нельзя, можно так: K>
K>*(&vectorObj[0] + 7)
K>
K>а надо так: K>
K>*(vectorObj.begin() + 7)
K>
Сомнительно...
Отдельные подозрительные личности утверждают, что &v[0] можно заменить на v.begin(), поскольку begin возвращает итератор, а для vector итератор в действительности представляет собой указатель. Во многих случаях это действительно так, но [...] это правило соблюдается не всегда, и полагаться на него не стоит. Функция begin возвращает итератор, а не указатель, поэтому она никогда не должна использоваться для получения указателя на данные vector. А если уже вам очень приглянулась запись v.begin(), используйте конструкцию &*v.begin() — она вернет тот же указатель, что и &v[0], хотя это увеличивает количество вводимых символов и затрудняет работу людей, пытающихся разобраться в вашей программе. Если знакомые вам советуют использовать v.begin() вместо &v[0] — лучше смените круг общения.
Скотт Мейерс, "Эффективное использование STL"
Думай, прежде чем родиться в этой сказочной стране!
(с) Антон Духовской
Здравствуйте, Комаров Иван, Вы писали:
КИ>Сомнительно...
это точно
КИ>
КИ>Отдельные подозрительные личности утверждают, что &v[0] можно заменить на v.begin(), поскольку begin возвращает итератор, а для vector итератор в действительности представляет собой указатель. Во многих случаях это действительно так, но [...] это правило соблюдается не всегда, и полагаться на него не стоит. Функция begin возвращает итератор, а не указатель, поэтому она никогда не должна использоваться для получения указателя на данные vector. А если уже вам очень приглянулась запись v.begin(), используйте конструкцию &*v.begin() — она вернет тот же указатель, что и &v[0], хотя это увеличивает количество вводимых символов и затрудняет работу людей, пытающихся разобраться в вашей программе. Если знакомые вам советуют использовать v.begin() вместо &v[0] — лучше смените круг общения.
Скотт Мейерс, "Эффективное использование STL"
я думаю что Мэйерс писал свою книгу на основе стандарта 98 года, в котором не требовалось чтобы vector хранил данные последовательно.
Но после 2000 года были поправки в стандарт и там требовалось чтобы буфер хранил данные последовательно чтобы его можно было использовать вместо сишных массивов и возможно там требовалось чтобы итераторы у вектора были указателями.
Это всё моё имхо.
Может владельцы поправок к стандарту просветят нас в этом вопросе?
Здравствуйте, Аноним, Вы писали:
А>Имеется вектор, забитый указателями на объект одного класса. В одной из функции я хочу вернуть указатель на 7-й элемент этого вектора, в вызывающую функцию и уже в ней обращаться с помощью адресной арифметики к элементам (указателям) вектора, расположенным за 7-м элементом. Возможно ли такое? Если бы был просто массив указателей — arr[200], я бы вернул arr, и уже работал бы так arr + 8... arr + 9 . Спасибо
Как Вам уже ответели, адрес взять-то конечно можно, но обратите внимание, на то что после этого ничего в вектор добавлять не стоит, ибо после добавления n-го (где n >= capacity) все ранее взятые указатели перестанут быть валидными.
Здравствуйте, korzhik, Вы писали:
K>я думаю что Мэйерс писал свою книгу на основе стандарта 98 года, в котором не требовалось чтобы vector хранил данные последовательно. K>Но после 2000 года были поправки в стандарт и там требовалось чтобы буфер хранил данные последовательно чтобы его можно было использовать вместо сишных массивов и возможно там требовалось чтобы итераторы у вектора были указателями.
Требование к последовательности есть, а вот требования чтобы итераторы были указателями нет.
Так что итератор в векторе != указатель.
Здравствуйте, _nn_, Вы писали:
__>Здравствуйте, korzhik, Вы писали:
K>>я думаю что Мэйерс писал свою книгу на основе стандарта 98 года, в котором не требовалось чтобы vector хранил данные последовательно. K>>Но после 2000 года были поправки в стандарт и там требовалось чтобы буфер хранил данные последовательно чтобы его можно было использовать вместо сишных массивов и возможно там требовалось чтобы итераторы у вектора были указателями. __>Требование к последовательности есть, а вот требования чтобы итераторы были указателями нет. __>Так что итератор в векторе != указатель.
Здравствуйте, korzhik, Вы писали:
K>Здравствуйте, _nn_, Вы писали:
__>>Здравствуйте, korzhik, Вы писали:
K>>>я думаю что Мэйерс писал свою книгу на основе стандарта 98 года, в котором не требовалось чтобы vector хранил данные последовательно. K>>>Но после 2000 года были поправки в стандарт и там требовалось чтобы буфер хранил данные последовательно чтобы его можно было использовать вместо сишных массивов и возможно там требовалось чтобы итераторы у вектора были указателями. __>>Требование к последовательности есть, а вот требования чтобы итераторы были указателями нет. __>>Так что итератор в векторе != указатель.
K>если ещё и цитату кинешь, то будет ваще ништяк
Цитату что-то не нахожу точную.
Может этого хватит :
namespace std {
template <class T, class Allocator = allocator<T> >
class vector {
public:
// types:
typedef typename Allocator::reference reference;
typedef typename Allocator::const_reference const_reference;
typedef implementation defined iterator; // See 23.1
typedef implementation defined const_iterator; // See 23.1
typedef implementation defined size_type; // See 23.1
typedef implementation defined difference_type;// See 23.1
//...
Здравствуйте, korzhik, Вы писали:
K>Здравствуйте, _nn_, Вы писали:
__>>Здравствуйте, korzhik, Вы писали:
K>>>я думаю что Мэйерс писал свою книгу на основе стандарта 98 года, в котором не требовалось чтобы vector хранил данные последовательно. K>>>Но после 2000 года были поправки в стандарт и там требовалось чтобы буфер хранил данные последовательно чтобы его можно было использовать вместо сишных массивов и возможно там требовалось чтобы итераторы у вектора были указателями. __>>Требование к последовательности есть
Вот оно :
23.2.4 Class template vector
1 A vector is a kind of sequence that supports random access iterators. In addition, it supports (amortized) constant time insert and erase operations at the end; insert and erase in the middle take linear time. Storage management is handled automatically, though hints can be given to improve efficiency. The elements of a vector are stored contiguously, meaning that if v is a vector<T, Allocator> where T is some type
other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().
Здравствуйте, korzhik, Вы писали:
K>если ещё и цитату кинешь, то будет ваще ништяк
Replace subclause 23.2.4, paragraph 1.
Original:
1 A vector is a kind of sequence that supports random access iterators. In addition, it supports (amortized)
constant time insert and erase operations at the end; insert and erase in the middle take linear time. Storage
management is handled automatically, though hints can be given to improve efficiency.
Replacement:
1 A vector is a kind of sequence that supports random access iterators. In addition, it supports (amortized)
constant time insert and erase operations at the end; insert and erase in the middle take linear time. Storage
management is handled automatically, though hints can be given to improve efficiency. The elements of a
vector are stored contiguously, meaning that if v is a vector<T, Allocator> where T is some type
other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().
Насчтет же итераторов стандарт говорит только то, что они implementation defined.