Имеется вектор, забитый указателями на объект одного класса. В одной из функции я хочу вернуть указатель на 7-й элемент этого вектора, в вызывающую функцию и уже в ней обращаться с помощью адресной арифметики к элементам (указателям) вектора, расположенным за 7-м элементом. Возможно ли такое? Если бы был просто массив указателей — arr[200], я бы вернул arr, и уже работал бы так arr + 8... arr + 9 . Спасибо
Здравствуйте, Аноним, Вы писали:
А>Имеется вектор, забитый указателями на объект одного класса. В одной из функции я хочу вернуть указатель на 7-й элемент этого вектора, в вызывающую функцию и уже в ней обращаться с помощью адресной арифметики к элементам (указателям) вектора, расположенным за 7-м элементом. Возможно ли такое? Если бы был просто массив указателей — arr[200], я бы вернул arr, и уже работал бы так arr + 8... arr + 9 . Спасибо
возможно.
vector как раз и задумывался как замена обычному массиву.
только зачем извращаться так?
передавай итератор.
Re[2]: std::vector
От:
Аноним
Дата:
15.09.04 09:01
Оценка:
Здравствуйте, korzhik, Вы писали:
K>Здравствуйте, Аноним, Вы писали:
А>>Имеется вектор, забитый указателями на объект одного класса. В одной из функции я хочу вернуть указатель на 7-й элемент этого вектора, в вызывающую функцию и уже в ней обращаться с помощью адресной арифметики к элементам (указателям) вектора, расположенным за 7-м элементом. Возможно ли такое? Если бы был просто массив указателей — arr[200], я бы вернул arr, и уже работал бы так arr + 8... arr + 9 . Спасибо
K>возможно. K>vector как раз и задумывался как замена обычному массиву.
K>только зачем извращаться так? K>передавай итератор.
В смысле я могу сделать так: vectorObj + 7, а если двумерный, да еще невыровненный???
Здравствуйте, Аноним, Вы писали:
K>>возможно. K>>vector как раз и задумывался как замена обычному массиву.
K>>только зачем извращаться так? K>>передавай итератор.
А>В смысле я могу сделать так: vectorObj + 7, а если двумерный, да еще невыровненный???
ну ты даёшь! задаёшь вопрос про одно, а потом оказывается что уже всё изменилось.
во первых что такое vectorObj?
ну ладно ругаться больше не буду, а лучше достану свой хрустальный шар и немного потелепатирую...
а вот теперь вижу, что vectorObj это std::vector<MyClass*> vectorObj
Теперь отвечаю: вот так vectorObj + 7 делать нельзя, можно так:
Здравствуйте, Аноним, Вы писали:
А>Имеется вектор, забитый указателями на объект одного класса. В одной из функции я хочу вернуть указатель на 7-й элемент этого вектора, в вызывающую функцию и уже в ней обращаться с помощью адресной арифметики к элементам (указателям) вектора, расположенным за 7-м элементом. Возможно ли такое? Если бы был просто массив указателей — arr[200], я бы вернул arr, и уже работал бы так arr + 8... arr + 9 . Спасибо
std::vector хранит свои элементы в непрерывном блоке памяти. Адрес первого элемента можно получить так:
std::vector<int> arr;
...
int* ptr = &arr[0];
или
int* ptr = &arr.front();
или
int* ptr = &(*arr.begin());
ptr[i] = ...;
Любите книгу — источник знаний (с) М.Горький
Re[4]: std::vector
От:
Аноним
Дата:
15.09.04 09:37
Оценка:
Здравствуйте, korzhik, Вы писали:
K>Здравствуйте, Аноним, Вы писали:
K>>>возможно. K>>>vector как раз и задумывался как замена обычному массиву.
K>>>только зачем извращаться так? K>>>передавай итератор.
А>>В смысле я могу сделать так: vectorObj + 7, а если двумерный, да еще невыровненный???
K>ну ты даёшь! задаёшь вопрос про одно, а потом оказывается что уже всё изменилось.
K>во первых что такое vectorObj?
K>ну ладно ругаться больше не буду, а лучше достану свой хрустальный шар и немного потелепатирую... K>а вот теперь вижу, что vectorObj это std::vector<MyClass*> vectorObj K>Теперь отвечаю: вот так vectorObj + 7 делать нельзя, можно так: K>
K>*(&vectorObj[0] + 7)
K>
K>а надо так: K>
K>*(vectorObj.begin() + 7)
K>
K>Встречный вопрос: слово итератор тебе знакомо?
Только знакомо, сам не работал и не представляю как. Научи
Re[4]: std::vector
От:
Аноним
Дата:
15.09.04 09:39
Оценка:
Здравствуйте, korzhik, Вы писали:
K>Здравствуйте, Аноним, Вы писали:
K>>>возможно. K>>>vector как раз и задумывался как замена обычному массиву.
K>>>только зачем извращаться так? K>>>передавай итератор.
А>>В смысле я могу сделать так: vectorObj + 7, а если двумерный, да еще невыровненный???
K>ну ты даёшь! задаёшь вопрос про одно, а потом оказывается что уже всё изменилось.
K>во первых что такое vectorObj?
K>ну ладно ругаться больше не буду, а лучше достану свой хрустальный шар и немного потелепатирую... K>а вот теперь вижу, что vectorObj это std::vector<MyClass*> vectorObj K>Теперь отвечаю: вот так vectorObj + 7 делать нельзя, можно так: K>
K>*(&vectorObj[0] + 7)
K>
K>а надо так: K>
K>*(vectorObj.begin() + 7)
K>
K>Встречный вопрос: слово итератор тебе знакомо?
На самом деле вектор двумерный, да еще невыровненный.
Здравствуйте, Аноним, Вы писали:
K>>Встречный вопрос: слово итератор тебе знакомо? А>Только знакомо, сам не работал и не представляю как. Научи
ну в общем итератор это обобщённый указатель.
служит для того чтобы перебирать элементы какой-нибудь последовательности.
Более подробно нет времени объяснять, читай книги по STL и паттернам программирования.
применительно к контейнерам STL и в частности к std::vector:
есть два метода begin() и end(), которые возвращают итераторы.
begin() возвращает итератор на первый элемент последовательности
end() возвращает итератор на место следующее сразу за последним элементом.
пример:
std::vector<int> arr;
for (int i = 0; i < 5; ++i)
{
arr.push_back(i);
}
имеем такую ситуацию:
arr: 1, 2, 3, 4 ^
^ |
| |
arr.begin() arr.end()
то есть мы можем пройтись по нашей последовательности с помощью итераторов:
std::vector<int>::iterator it = arr.begin();
std::vector<int>::iterator last = arr.end();
for (; it != last; ++it)
{
std::cout << *it << std::endl;
}
итераторы бывают разных категорий (подробнее в книгах)
у vectora итератор произвольного доступа, то есть ты можешь делать так:
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, korzhik, Вы писали:
K>>Здравствуйте, Аноним, Вы писали:
K>>>>возможно. K>>>>vector как раз и задумывался как замена обычному массиву.
K>>>>только зачем извращаться так? K>>>>передавай итератор.
А>>>В смысле я могу сделать так: vectorObj + 7, а если двумерный, да еще невыровненный???
K>>ну ты даёшь! задаёшь вопрос про одно, а потом оказывается что уже всё изменилось.
K>>во первых что такое vectorObj?
K>>ну ладно ругаться больше не буду, а лучше достану свой хрустальный шар и немного потелепатирую... K>>а вот теперь вижу, что vectorObj это std::vector<MyClass*> vectorObj K>>Теперь отвечаю: вот так vectorObj + 7 делать нельзя, можно так: K>>
K>>*(&vectorObj[0] + 7)
K>>
K>>а надо так: K>>
K>>*(vectorObj.begin() + 7)
K>>
K>>Встречный вопрос: слово итератор тебе знакомо? А>Только знакомо, сам не работал и не представляю как. Научи
Здравствуйте, Анатолий Широков, Вы писали:
А>>На самом деле вектор двумерный, да еще невыровненный.
АШ>У вас примерно такая структура std::vector<myobject*> vec?
АШ>Если да, то тогда, чтобы работать с 7 строкой матрицы используйте vec[6]. А для обращения к элементам строки vec[6][0] и т.д.
АШ>В противном случае, проясните ситуацию.
Вы правильно меня поняли (извиняюсь, если ввел в заблуждение, надо было мне сразу писать все как есть)! Нужно получить указатель на начало 6 строки двумерного вектора и уже после перебрать все столбцы в этой 6-й строке
Re[7]: std::vector
От:
Аноним
Дата:
15.09.04 10:03
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Анатолий Широков, Вы писали:
А>>>На самом деле вектор двумерный, да еще невыровненный.
АШ>>У вас примерно такая структура std::vector<myobject*> vec?
АШ>>Если да, то тогда, чтобы работать с 7 строкой матрицы используйте vec[6]. А для обращения к элементам строки vec[6][0] и т.д.
АШ>>В противном случае, проясните ситуацию.
А>Вы правильно меня поняли (извиняюсь, если ввел в заблуждение, надо было мне сразу писать все как есть)! Нужно получить указатель на начало 6 строки двумерного вектора и уже после перебрать все столбцы в этой 6-й строке
Нужно видимо так Obj *myobj = &vector[6][0], далее myobj + 1, + 2, до конца строки. Правильно
А>Вы правильно меня поняли (извиняюсь, если ввел в заблуждение, надо было мне сразу писать все как есть)! Нужно получить указатель на начало 6 строки двумерного вектора и уже после перебрать все столбцы в этой 6-й строке
Здравствуйте, Аноним, Вы писали:
А>Вы правильно меня поняли (извиняюсь, если ввел в заблуждение, надо было мне сразу писать все как есть)!
Да, если правильно описать проблему, то решение находится гораздо быстрее
А>Нужно получить указатель на начало 6 строки двумерного вектора и уже после перебрать все столбцы в этой 6-й строке
std::vector<std::vector<int> > arr2d;
...
int* pRow6 = &arr2d[6][0];
или
int* pRow6 = &(*arr2d[6].begin());
или
int* pRow6 = &arr2d[6].front();
Здравствуйте, Анатолий Широков, Вы писали:
А>>Нужно видимо так Obj *myobj = &vector[6][0], далее myobj + 1, + 2, до конца строки. Правильно
АШ>Можно проще:
АШ>
АШ>Obj *myobj = vector[6];
АШ>
АШ>А далее myobj + 1, + 2
По-моему все окончательно запутались
Насколько я понимаю ситуацию, имеется
std::vector<std::vector<Obj*> > vec;
и поэтому "обычный" указатель на строку нужно получать так:
И вроде автор подтвердил, что имеем дело с std::vector<myobject*>, но а там кто его знает
Re[9]: std::vector
От:
Аноним
Дата:
15.09.04 10:25
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:
А>>Нужно видимо так Obj *myobj = &vector[6][0], далее myobj + 1, + 2, до конца строки. Правильно
АШ>Можно проще:
АШ>
АШ>Obj *myobj = vector[6];
АШ>
АШ>А далее myobj + 1, + 2
Спасибо
Re[9]: std::vector
От:
Аноним
Дата:
15.09.04 10:26
Оценка:
Здравствуйте, kvas, Вы писали:
K>Здравствуйте, Bell, Вы писали:
B>>
Здравствуйте, 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.