Иногда мне нужно преобразовать векторные итераторы в указатели. Я знаю, что есть несколько способов сделать это, например, vector::data
, но мне интересно узнать о действии &(*some_vector.end())
. Я знаю разыменование конца вектора - это неопределенное поведение, но кажется, что оператору &
не нужно значение выражения, и, следовательно, конечный итератор не будет разыменован в этом выражении. Это верно? Или это еще неопределенное поведение?Является ли выражение `& (* some_vector.end())« корректным »?
ответ
Пробег: data()+end()-begin()
.
В то время как итераторы vector
могут быть реализованы как необработанные указатели, они не обязательно должны быть. Разделение итератора не определено, если это итератор end
, что на практике означает, что итераторы могут быть отладки, чтобы обнаружить этот случай, и компилятор может на законных основания предположить, что вы этого никогда не делаете. Таким образом, заявление &*it-&*begin() >= size()
может легально, по стандарту, рассматриваться как false
.
Хотя это может быть смешно, GCC делает аналогичные оптимизации с подписанным переполнением, где аппаратное обеспечение делает одно, но компилятор не предполагает, что ничего неопределенного не происходит, и он может отбрасывать целые ветви кода, которые пытаются обнаружить переполнение.
Это имеет смысл. –
Предпосылкой разыменования итератора является то, что он отличается от конечного итератора. Даже если все, что вы делаете с результатом, это принять его адрес, это все еще неопределенное поведение.
'* some_vector.end()' все еще пытается разыменовать конец() – billz