是否可以安全地寻找std::string::iterator
某个位置?
std :: string :: iterator有一个偏移访问运算符(operator []),但它存在于某些人定义的类别中,如未定义的行为,如it + 3
。
答案 0 :(得分:2)
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
答案 1 :(得分:1)
我不知道你认为operator[]
是std::string::iterator
的UB的想法。它被定义为随机访问迭代器,它支持i[n]
以及i + n
。
基于其他地方的评论,看起来你是在绝对定位之后(从问题的措辞来看,这不是很清楚)。你不能从你不知道的位置的迭代器那里做到这一点,但你可以通过相对于begin()
返回的迭代器的偏移来实现相同的效果,即:str.begin()[3]
或{{1} }。如果你没有方便的原始字符串,你就被软管了。
答案 2 :(得分:1)
标准迭代器的指定方式使它们不需要引用它们迭代的容器(或其他序列);这意味着只使用迭代器就无法进行“绝对搜索”。你需要从字符串中获取一个新的迭代器,检查它是否在范围内;类似的东西:
std::string::iterator seek(std::string & s, size_t i) {
return s.length() <= i ? s.end() : s.begin() + i;
}
只要你保持在范围内,就可以很好地定义随机访问迭代器和字符串上的operator[]
的算法。如果超出范围,行为仅是未定义的。