簡體   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