string::iterator it;
for (it = str.begin(); it < str.end(); it++)
cout << *it;
cout << endl;
为什么不:
for (int i = 0; i < str.size(); i++)
cout << str[i];
cout << endl;
似乎string :: iterator也没有提供范围检查。我们为什么要使用string::iterator
而不是索引?
感谢。
答案 0 :(得分:27)
索引只能用于支持随机访问的容器 - 直接访问给定位置。
迭代器提供了一种访问任何集合/数据结构的统一方法。重构代码时的灵活性是巨大的。
答案 1 :(得分:17)
迭代器是标准接口。通过使用迭代器,您可以对不同的容器使用相同的算法。是否使用它们的最终决定取决于可用性和可读性。
例如,使用标准变换算法将std::string
转换为大写:
std::string str = "A String";
std::transform(str.begin(), str.end(), str.begin(), ::toupper);
将导致str
等于"A STRING"
。
答案 2 :(得分:5)
对于std :: string,我建议您使用索引,因为它支持随机访问,并且更简单。它“推荐”使用迭代器的唯一原因是因为迭代器提供了访问序列的标准接口,因此如果您的序列更改为std :: list,则迭代代码将保持不受影响
答案 3 :(得分:2)
重复:
那就是说,这是一个普遍性的问题。您可以使用STL比使用数组访问更多地使用迭代器执行 lot 。此外,如果您需要重构代码,并将字符串更改为向量,列表或rope,则根本不必重写代码。
最后,迭代中存在安全问题。如果你想在你的循环中访问 中的NEXT字符,你可以安全地使用迭代器,但增加数组下标可能会在最后一个元素上出现段错误,因此需要另外检查。
答案 4 :(得分:1)
如上所述in this question,size()方法不保证为O(1)
答案 5 :(得分:1)
如果您不知道要迭代哪个类(因为它是模板参数),您应该使用迭代器,因为并非每个提供迭代器的类都提供[]
(而不是每个提供[]
的类,提供一个在O(1)时间内工作的类。因此,通过使用迭代器,您将确保该函数可以使用尽可能多的类(尽管不使用C数组)。
在这个具体案例中,除了个人偏好或可能过早优化外,我认为没有理由偏好其他人。
答案 6 :(得分:0)
两者都有效。
主要原因是一致性:通过请求迭代器并使其前进,您以相同的方式迭代集合或字符串的字符。
我不想说++it
的实现细节导致指针增量与涉及指针算术的str[i]
相比值得一提。范围检查也是实现细节。
答案 7 :(得分:0)
迭代器更安全,并提供更多的灵活性,如其他人发布的那样。另外,索引只能用于(有效)支持随机的容器 访问(即直接访问给定位置的元素)。迭代器是一个更通用的概念。迭代器提供链接列表,文件和许多其他数据结构的有效遍历。它通常会导致生成更高效的代码。
答案 8 :(得分:0)
我假设迭代器应该优先于索引的另一个原因是并非所有集合都支持恒定时间随机访问。
例如,如果您想要链接列表中的 n -th元素,则需要遍历所有前面的元素(索引为0 .. n-1 )直到你到达 n -th元素。 (此操作需要线性时间。)
(顺序)迭代器会记住它在集合中的位置,并且当您想要下一个元素时,并不总是必须从头开始。在您的示例中,您实际上不需要以随机顺序访问字符串中的字符,而只是按顺序访问,因此使用迭代器几乎肯定会更快(恒定时间)。
答案 9 :(得分:-2)
在C ++中,你可以通过许多不同的方式做很多事情。这是另一个例子。 在这种情况下,使用哪种方法没有区别。但总的来说,迭代器更快,更安全,并且在不同类型的容器中提供更大的灵活性。