繁体   English   中英

需要澄清C ++ std :: iterator

[英]Need clarification about C++ std::iterator

阅读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的元素的“指针”吗?

谢谢。

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

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

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

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

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

大多; 迭代器不是(必然)指针,它们有点是指针概念的概括。 它们用于指向存储在容器内的特定对象(在本例中是字符串中的字符),您可以使用它们在字符串的元素之间移动(通过常用的算术运算符 - 当它们受支持时)并且您“取消引用“用*来获取对尖头物体的引用。

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

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

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

这里存储向量索引的等价物就是存储哈希表的密钥,但是(1)它们是字符串(因此它们分配和处理成本相当高),以及(2)使用它们到达我必须做的相应对象另一个哈希表查找稍后。 相反,将迭代器存储在向量中可以保证存储字符串没有麻烦(迭代器的处理成本很低)并且不需要再次执行查找。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM