Рассмотрим следующий фрагмент кода
void foo( bool forwad )
{
vector<MyObject>::iterator it, end_it;
int dir;
it = some_global_vector.begin() + some_position;
if( forward )
{
dir = 1;
it += 1;
end_it = some_global_vector.end();
}
else
{
dir = -1;
it -= 1;
end_it = some_global_vector.begin()-1;
}
while( it != end_it )
{
if( do_domething() )
break;
it += dir;
}
}
Как вы можете видеть, есть некоторые сомнения, когда forward == false
, потому что есть вычитание из begin()
и итератор it
может быть вычтен, когда он указывает на begin()
. Я нигде не могу найти, если это нормально, пока я не разыграю этот плохой указывающий итератор).
EDIT
Я прочитал стандарт ISO C ++ и у меня есть некоторые выводы.
Нет никаких обещаний, что vector::begin()
не сможет внутренне указать на память по адресу 0
, и я подумал, что это конец, но все контейнеры зависят от стандартного локатора. Этот локатор зависит от оператора new
. А также нет информации о том, что new
никогда не вернет 0
. Но стандартный локатор зависит также от оператора delete
, и этот оператор может ничего не делать, если вы передадите 0
. Таким образом, по этому факту new
не может вернуть 0
, потому что не будет никакого способа удалить этот указатель, и при этом непустой vector
не может вернуть begin()
, который указывает на 0
.
Вывод:
Если выше - правый убывающий интегратор, который указывает на vector::begin()
, должен быть безопасным, поскольку внутренняя память vector
является непрерывной.
Я прав?
ОТЛИЧНЫЙ ОТВЕТ
Даже если он работает сейчас и будет работать в будущем, это ненадлежащее поведение в соответствии со стандартом. Если вы делаете это, вы делаете это на свой страх и риск. См. Этот simmilar вопрос для получения дополнительной информации.