Можно ли искать std::string::iterator
безопасно в данной позиции?
std :: string :: iterator имеет оператор доступа со смещением (operator []), но он существует в категории, определенной некоторыми людьми как неопределенное поведение, например it + 3
,
У std :: string :: iterator есть оператор доступа со смещением (operator []), но он существует в категории, определенной некоторыми людьми как неопределенное поведение, например, + 3.
Я не понимаю это утверждение. Нет такой категории. std::basic_string<>::iterator
является итератором с произвольным доступом, поэтому его можно искать, просто добавляя или вычитая смещение к нему или из него (что соответствует документации, с которой вы связаны):
auto new_it = it + offset;
То, что не определено, ищет мимо end()
итератор связанного контейнера или перед его началом. То есть следующее неопределенное поведение:
std::string str = "hi";
auto it1 = str.begin() + 2; // OK.
assert(it1 == str.end());
auto it2 = str.begin() + 3; // UB!
// At this point we cannot assert anything about it2
Стандартные итераторы задаются таким образом, что им не нужно обращаться к контейнеру (или другой последовательности), что они выполняют итератор; это означает, что нет никакого способа сделать «абсолютный поиск», используя только итератор. Вам нужно будет получить новый итератор из строки, проверяя себя, что он находится в диапазоне; что-то вроде:
std::string::iterator seek(std::string & s, size_t i) {
return s.length() <= i ? s.end() : s.begin() + i;
}
Арифметика на итераторах с произвольным доступом и operator[]
на строках четко определены, пока вы остаетесь в пределах досягаемости. Поведение не определено, только если вы выходите из диапазона.
Я не знаю, откуда у вас мысль, что operator[]
UB для std::string::iterator
, Он определяется как итератор с произвольным доступом, который поддерживает i[n]
так же как i + n
,
Судя по комментариям в других местах, кажется, что вы после абсолютного позиционирования (это не очень ясно из формулировки вашего вопроса). Вы не можете сделать это из итератора, чья позиция вам неизвестна, но вы можете добиться того же эффекта, смещаясь относительно итератора, возвращаемого begin()
т.е. str.begin()[3]
или же str.begin() + 3
, Если у вас нет оригинальной строки под рукой, вы попали.