需要澄清C++ std::iterator

Need clarification about C++ std::iterator

本文关键字:std iterator C++      更新时间:2023-10-16

阅读C++书时,我遇到了以下使用迭代器的示例:

vector<string::iterator> find_all(string& s, char c)
{
    vector<string::iterator> res;
    for(auto p = s.begin(); p != s.end(); ++p)
        if(*p == c)
            res.push_back(p);
    return res;
}
void test()
{
    string m {"Mary had a little lamb"};
    for(auto p : find_all(m, 'a'))
        if(*p != 'a')
            cerr << "a bug!n";
}

我对 find_all() 返回的向量包含的内容有点困惑。它本质上是指向在其上方创建的字符串 m 元素的"指针"吗?

谢谢。

我对 find_all() 返回的向量包含的内容有点困惑。它本质上是指向在其上方创建的字符串 m 元素的"指针"吗?

大多数情况下,迭代器不是(必然)指针,它们在某种程度上是指针概念的概括。它们用于指向存储在容器中的特定对象(在本例中为字符串内的字符),您可以使用它们在字符串的元素之间移动(通过通常的算术运算符 - 当它们受支持时),并且您可以使用*"取消引用"它们以获取对指向对象的引用。

请注意,根据容器的不同,它们的实现方式不同,并提供不同的功能;例如,std::list的迭代器将允许++--和*,但不会移动到任意位置,并且单向链表的迭代器甚至不支持--,而通常迭代到类似数组的数据结构(如vectorstring)将允许完全自由移动。

要引用类数组结构中的元素,通常只存储索引,因为它们存储和使用成本低;相反,对于其他结构,存储迭代器可能更方便。

例如,就在昨天,我有一些代码走过一个unordered_set<string, int>(=一个将一些单词映射到它们的出现的哈希表)来"注意"一些(字符串,int)对,以便以后使用它们。

在这里存储向量索引的等效物是存储哈希表的键,但是 (1) 它们是字符串(因此分配和处理它们的成本适中),以及 (2) 要使用它们到达相应的对象,我不得不稍后再做一次哈希表查找。相反,将迭代器存储在向量中可以保证存储字符串时没有麻烦(迭代器旨在便宜地处理),并且无需再次执行查找。

是的,迭代器就像指针。 std::string::iterator甚至可以是char *的别名,尽管通常不是。

通常,迭代器提供指针功能的子集。哪个子集取决于迭代器。你的书可能涵盖了这一点,但所有的迭代器都可以取消引用(*,但从来没有引用&操作)和递增(++),然后一些额外提供--,有些在此基础上添加+-

在这种情况下,该函数似乎假设您只会查询迭代器的值而不修改字符串。由于用于字符串存储的分配块可能会随着字符串的增长而更改,因此字符串中的迭代器(如指针)可能会失效。这就是为什么std::string成员函数(如string::find)返回索引号,而不是迭代器。

索引向量可能是更好的设计选择,但对于一个示例来说,这已经足够了。