简体   繁体   English

需要澄清C ++ std :: iterator

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

Reading a C++ book I encountered the following example on using iterators: 阅读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";
}

I'm a little confused about what the vector returned by find_all() contains. 我对find_all()返回的向量包含的内容有点困惑。 Is it essentially "pointers" to the elements of the string m created above it? 它本质上是指向它上面创建的字符串m的元素的“指针”吗?

Thanks. 谢谢。

Yes, iterators are like pointers. 是的,迭代器就像指针一样。 std::string::iterator can even be an alias for char * , although it's usually not. std::string::iterator甚至可以是char *的别名,尽管通常不是。

In general, iterators provide a subset of pointer functionality. 通常,迭代器提供指针功能的子集。 Which subset depends on the iterator. 哪个子集取决于迭代器。 Your book probably covers this, but all iterators can be dereferenced ( * , but there is never a reference & operation) and incremented ( ++ ), then some additionally provide -- , and some add + and - on top of that. 你的书可能涵盖了这一点,但是所有的迭代器都可以被解除引用( * ,但是从来没有引用&操作)和递增( ++ ),然后一些额外提供-- ,并且一些添加+-在它之上。

In this case, the function seems to assume you will only be querying the values of the iterators without modifying the string. 在这种情况下,函数似乎假设您只是在不修改字符串的情况下查询迭代器的值。 Because the allocation block used for string storage may change as the string grows, iterators (like pointers) into the string may be invalidated. 因为用于字符串存储的分配块可能随着字符串的增长而改变,所以字符串中的迭代器(如指针)可能无效。 This is why std::string member functions like string::find return index numbers, not iterators. 这就是为什么std::string成员函数像string::find返回索引号而不是迭代器。

A vector of indexes could be a better design choice, but this is good enough for an example. 索引向量可能是更好的设计选择,但这对于一个例子来说已经足够了。

I'm a little confused about what the vector returned by find_all() contains. 我对find_all()返回的向量包含的内容有点困惑。 Is it essentially "pointers" to the elements of the string m created above it? 它本质上是指向它上面创建的字符串m的元素的“指针”吗?

Mostly; 大多; iterators aren't (necessarily) pointers, they are somewhat a generalization of the pointer concept. 迭代器不是(必然)指针,它们有点是指针概念的概括。 They are used to point to specific objects stored inside containers (in this case, characters inside a string), you can use them to move between the elements of the string (via the usual arithmetic operators - when they are supported) and you "dereference" them with * to get a reference to the pointed object. 它们用于指向存储在容器内的特定对象(在本例中是字符串中的字符),您可以使用它们在字符串的元素之间移动(通过常用的算术运算符 - 当它们受支持时)并且您“取消引用“用*来获取对尖头物体的引用。

Notice that, depending from the container, they are implemented differently and provide different features; 请注意,根据容器的不同,它们的实现方式不同,并提供不同的功能; an iterator to a std::list , for example, will allow ++ , -- and *, but not moving to arbitrary locations, and an iterator to a singly-linked list won't even support -- , while typically iterators to array-like data structures (like vector or string ) will allow completely free movement. 例如, std::list的迭代器将允许++--和*,但不会移动到任意位置,并且单链接列表的迭代器甚至不支持--虽然通常是迭代器类似数组的数据结构(如vectorstring )将允许完全自由移动。

To refer to elements in array-like structures often one just stores indexes, since they are cheap to store and use; 为了引用类似数组的结构中的元素,通常只存储索引,因为它们便于存储和使用; for other structures, instead, storing iterators may be more convenient. 对于其他结构,相反,存储迭代器可能更方便。

For example, just yesterday I had some code which walked a unordered_set<string, int> (=a hashtable that mapped some words to their occurrences) to "take note" of some of the (string, int) couples to use them later. 例如,就在昨天我有一些代码走了一个unordered_set<string, int> (=一个哈希表,将一些单词映射到它们的出现位置),以“注意”一些(字符串,整数)对,以便稍后使用它们。

The equivalent of storing vector indexes here would have been storing the hashtable's keys, but (1) they are strings (so they are moderately costly to allocate and handle), and (2) to use them to reach the corresponding object I had to do another hashtable lookup later. 这里存储向量索引的等价物就是存储哈希表的密钥,但是(1)它们是字符串(因此它们分配和处理成本相当高),以及(2)使用它们到达我必须做的相应对象另一个哈希表查找稍后。 Instead, storing iterators in a vector guarantees no hassle for storing strings (iterators are intended to be cheap to handle) and no need to perform a lookup again. 相反,将迭代器存储在向量中可以保证存储字符串没有麻烦(迭代器的处理成本很低)并且不需要再次执行查找。

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

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