Reputation: 5681
Is it possible to seek a std::string::iterator
safely to a given position?
std::string::iterator has a offset access operator (operator []), but it exists in the category defined by some people as undefined behavior, like it + 3
.
Upvotes: 7
Views: 10869
Reputation: 185862
I don't know where you got the idea that operator[]
is UB for std::string::iterator
. It's defined as a random-access iterator, which supports i[n]
as well as i + n
.
Based on comments elsewhere, it appears you are after absolute positioning (That isn't very clear from the wording of your question). You can't do that from an iterator who's position you don't know, but you can achieve the same effect by offsetting relative to the iterator returned by begin()
, i.e.: str.begin()[3]
or str.begin() + 3
. If you don't have the original string handy, you're hosed.
Upvotes: 4
Reputation: 545618
std::string::iterator has a offset access operator (operator []), but it exists in the category defined by some people as undefined behavior, like it + 3.
I don’t understand this statement. There is no such category. std::basic_string<>::iterator
is a random access iterator and as such you can seek by just adding or subtracting an offset to / from it (which is consistent with the documentation you linked to):
auto new_it = it + offset;
What’s undefined is seeking past the end()
iterator of the associated container, or before its beginning. That is, the following is undefined behaviour:
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
Upvotes: 9
Reputation: 254471
Standard iterators are specified in such a way that they don't need to refer to the container (or other sequence) that they iterator over; this means that there is no way to do an "absolute seek" using just an iterator. You will need get a new iterator from the string, checking yourself that it's in range; something like:
std::string::iterator seek(std::string & s, size_t i) {
return s.length() <= i ? s.end() : s.begin() + i;
}
Arithmetic on random-access iterators, and operator[]
on strings, are well-defined as long as you stay within range. Behaviour is only undefined if you go out of range.
Upvotes: 1