Что говорит стандарт С++ о std::vector <int> v1, v2; станд:: расстояние (v1.begin(), v2.begin())?
У меня есть этот код
#include <vector>
#include <iostream>
int main(int argc, char* argv[])
{
std::vector<int> v1,v2;
std::cout << std::distance(v1.begin(),v2.begin());
return 0;
}
и он имеет ошибку, потому что не имеет смысла сравнивать итераторы двух разных векторов.
Я просмотрел N3376 в 24.4.4. Операции итератора на стр. 815:
template<class InputIterator>
typename iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last);
Требуется: Если InputIterator
соответствует требованиям итератора произвольного доступа, last
может достигать от first
или first
, должно быть достижимо от last
; в противном случае last
должно быть доступно из first
.
Теперь я думаю, что Requires не выполняется.
Что должно произойти в этом случае стандартное состояние?
Ответы
Ответ 1
[iterator.requirements.general]:
Итератор j
называется достижимым из итератора i
, если и только если существует конечная последовательность применений выражения ++i
что делает i == j
.
Проблема заключается в том, что после того, как вы увеличили v1.begin()
v1.size()-1
раз, следующая операция приращения вызывает поведение undefined, поэтому v2.begin()
не может быть достигнуто с v1.begin()
. Тот же аргумент делает v1.begin()
недоступным из v2.begin()
.
В случае, если у вас возник вопрос: "Что произойдет, если условие в разделе Requires нарушено?", посмотрите [res.on.required]:
Нарушение предусловий, указанных в функциях. Требуется: абзац приводит к поведению undefined, если функции Броски: Параметр указывает на исключение исключения, когда предварительное условие нарушены.
Ответ 2
В некоторых реализациях std::distance
первый итератор увеличивается до тех пор, пока не достигнет второго итератора. Итерации подсчитываются:
unsigned int counts = 0;
while (iter1 != iter2)
{
++counts;
++iter1;
}
Если итераторы указывают на контейнеры в разных адресных пространствах, цикл многих не заканчивается. Используя термины в стандарте, второй итератор недоступен.
Ответ 3
requires
не выполняется, что означает, что код имеет поведение undefined: все может случиться.
Ответ 4
В этом случае будет поведение undefined. Поскольку last
недоступен из first
(возможно, несколько раз), увеличивая first
.