3

是否有可能std::string::iterator安全地寻求一个给定的位置?

std::string::iterator 有一个偏移访问运算符(operator []),但它存在于某些人定义为未定义行为的类别中,例如it + 3.

cplusplus.com 参考

4

3 回答 3

4

std::string::iterator 有一个偏移访问运算符(operator []),但它存在于某些人定义为未定义行为的类别中,比如 it + 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
于 2012-12-20T11:35:12.020 回答
2

我不知道你从哪里得到operator[]UB的想法std::string::iterator。它被定义为一个随机访问迭代器,它i[n]支持i + n.

根据其他地方的评论,您似乎是在绝对定位之后(从您的问题的措辞中不是很清楚)。你不能从一个你不知道位置的迭代器做到这一点,但是你可以通过相对于由返回的迭代器进行偏移来实现相同的效果begin(),即:str.begin()[3]str.begin() + 3。如果您手边没有原始琴弦,那您就完蛋了。

于 2012-12-20T11:33:19.967 回答
1

标准迭代器的指定方式是它们不需要引用它们迭代的容器(或其他序列);这意味着无法仅使用迭代器进行“绝对搜索”。您需要从字符串中获取一个新的迭代器,检查自己是否在范围内;就像是:

std::string::iterator seek(std::string & s, size_t i) {
    return s.length() <= i ? s.end() : s.begin() + i;
}

operator[]只要您保持在范围内,随机访问迭代器和字符串的算术就已经定义明确。仅当您超出范围时,行为才不确定。

于 2012-12-20T11:33:57.327 回答