std::for_each и массивы
От: Gigachel Украина  
Дата: 14.03.06 09:22
Оценка:
Доброго дня.

Возник такой вопрос.
Есть массив объектов, например, типа CType и размерностью N;

CType arr[N];

Чтобы вызвать какой-нибудь метод на всех элементах массива CType::Func использую, к паримеру, такую инструкцию:

std::for_each(&arr[0],&arr[N],boost::mem_fn(&CType::Func,boost::ref(_1));

Как я понимаю, инструкция &arr[N] используется только на чтение для определения дошел
ли итератор for_each до конца массива. Но фактически это обращение за пределы массива
и даже попытка чтения адреса может вызвать access violation.

На VC++7.1 все нормально выполняется.

Посоветуйте, насколько корректна такая форма вызова и не ли тут каких-нибудь тонких моментов?

Спасибо.
Re: std::for_each и массивы
От: sadomovalex Россия http://sadomovalex.blogspot.com
Дата: 14.03.06 09:26
Оценка:
Здравствуйте, Gigachel, Вы писали:

используй такую запись:
std::for_each(arr, arr + N, ...);
"Что не завершено, не сделано вовсе" Гаусс
Re: std::for_each и массивы
От: sch  
Дата: 14.03.06 09:29
Оценка:
G>Как я понимаю, инструкция &arr[N] используется только на чтение для определения дошел
G>ли итератор for_each до конца массива. Но фактически это обращение за пределы массива
G>и даже попытка чтения адреса может вызвать access violation.

&arr[N] равнозначно (arr + N) -- если тебя смущет первый вариант записи, то используй второй.
Операции "чтения адреса" в природе не существует (не путать с чтением значения указателя из памяти).
Re: std::for_each и массивы
От: HiSH Россия http://m0riarty.ya.ru
Дата: 14.03.06 09:29
Оценка:
Здравствуйте, Gigachel, Вы писали:


G>std::for_each(&arr[0],&arr[N],boost::mem_fn(&CType::Func,boost::ref(_1));


G>Как я понимаю, инструкция &arr[N] используется только на чтение для определения дошел

G>ли итератор for_each до конца массива. Но фактически это обращение за пределы массива
G>и даже попытка чтения адреса может вызвать access violation.

Итератор end() (конца списка) устанавливается в позицию, следующую за последним элементом. То есть тут все верно. А в for_each будет код наподобие:
for (iter = begin_iter; iter != end_iter; iter++)
   ....
}

То есть никаких попыток чтения данных за пределами массива не будет.
... << RSDN@Home 1.1.4 stable SR1 rev. 568 with Queen — Sail Away Sweet Sister>>
Re: std::for_each и массивы
От: Bell Россия  
Дата: 14.03.06 09:31
Оценка: +2
Здравствуйте, Gigachel, Вы писали:

G>Как я понимаю, инструкция &arr[N] используется только на чтение для определения дошел

G>ли итератор for_each до конца массива. Но фактически это обращение за пределы массива
G>и даже попытка чтения адреса может вызвать access violation.

Правильно, поэтому следует использовать такую запись:
std::for_each(arr,arr+N,boost::mem_fn(&CType::Func,boost::ref(_1));

т.к. стандарт разрешает использование указателя на элемент-за-последним.
Любите книгу — источник знаний (с) М.Горький
Re[2]: std::for_each и массивы
От: Bell Россия  
Дата: 14.03.06 09:46
Оценка: +1
Здравствуйте, sch, Вы писали:

sch>&arr[N] равнозначно (arr + N) -- если тебя смущет первый вариант записи, то используй второй.

Нет — &arr[N] равнозначно такому выражению: &*(arr+N).
Любите книгу — источник знаний (с) М.Горький
Re[3]: std::for_each и массивы
От: sch  
Дата: 14.03.06 10:37
Оценка:
B>Нет — &arr[N] равнозначно такому выражению: &*(arr+N).

&*a = a по определению.
Re[4]: std::for_each и массивы
От: Аноним  
Дата: 14.03.06 11:09
Оценка:
Здравствуйте, sch, Вы писали:


B>>Нет — &arr[N] равнозначно такому выражению: &*(arr+N).


sch>&*a = a по определению.


Да? а если у тебя оператор * для класса перегружен ?
Re[4]: std::for_each и массивы
От: Шахтер Интернет  
Дата: 14.03.06 11:47
Оценка:
Здравствуйте, sch, Вы писали:


B>>Нет — &arr[N] равнозначно такому выражению: &*(arr+N).


sch>&*a = a по определению.


Не совсем. Если a сингулярен, то левая часть неопределена.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re: std::for_each и массивы
От: elcste  
Дата: 14.03.06 14:18
Оценка:
Здравствуйте, Gigachel, Вы писали:

G>CType arr[N];


G>std::for_each(&arr[0],&arr[N],boost::mem_fn(&CType::Func,boost::ref(_1));


G>Посоветуйте, насколько корректна такая форма вызова и не ли тут каких-нибудь тонких моментов?


Да, формально в C++ &arr[N] — неопределенное поведение (в C эта конструкция корректна).

Кстати, boost предоставляет обертку над массивом boost::array, которая позволяет работать со встроенным массивом теми же средствами, что и со стандартным контейнером.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.