【问题标题】:unordered_multimap - iterating the result of find() yields elements with different valueunordered_multimap - 迭代 find() 的结果会产生具有不同值的元素
【发布时间】:2012-02-21 05:55:10
【问题描述】:

C++ 中的多重映射似乎很奇怪,我想知道为什么

#include <iostream>
#include <unordered_map>

using namespace std;

typedef unordered_multimap<char,int> MyMap;

int main(int argc, char **argv)
{
    MyMap map;
    map.insert(MyMap::value_type('a', 1));
    map.insert(MyMap::value_type('b', 2));
    map.insert(MyMap::value_type('c', 3));
    map.insert(MyMap::value_type('d', 4));
    map.insert(MyMap::value_type('a', 7));
    map.insert(MyMap::value_type('b', 18));

    for(auto it = map.begin(); it != map.end(); it++) {
        cout << it->first << '\t';
        cout << it->second << endl;
    }

    cout << "all values to a" << endl;
    for(auto it = map.find('a'); it != map.end(); it++) {
        cout << it->first << '\t' << it->second << endl;
    }

}

这是输出:

c   3
d   4
a   1
a   7
b   2
b   18
all values to a
a   1
a   7
b   2
b   18

为什么当我明确要求'a'时,输出仍然包含以b为键的任何内容?这是编译器还是 stl 错误?

【问题讨论】:

    标签: c++ c++11 stl iteration unordered-map


    【解决方案1】:

    find 已实现,为与多重映射中的键匹配的第一个元素返回一个迭代器(与任何其他映射一样)。您可能正在寻找equal_range

    // Finds a range containing all elements whose key is k.
    // pair<iterator, iterator> equal_range(const key_type& k)
    auto its = map.equal_range('a');
    for (auto it = its.first; it != its.second; ++it) {
        cout << it->first << '\t' << it->second << endl;
    }
    

    【讨论】:

    • 请注意,标准不保证“find 在实现时返回第一个元素的迭代器”
    【解决方案2】:

    您似乎可以将迭代器放入完整的对“列表”中,从第一对以“a”为键开始。因此,当您迭代到最后时,您自然也会得到“a”之外的所有内容。如果你寻找'c',你可能会遍历整个“列表”来做你在那里做的事情。如果你想要所有的 a,也许你应该迭代到 "it != map.end() && it->first == 'a'"。

    【讨论】:

      【解决方案3】:

      这不是错误,这是设计使然。 find 将迭代器返回到匹配元素之一,仅此而已。您将使用您的构造迭代到地图的末尾。

      你需要使用multimap::equal_range 来做你想做的事。

      【讨论】:

        【解决方案4】:

        www.cplusplus.com 中有一个示例,关于如何使用 equal_range 方法获取具有相同键的所有元素。

        // unordered_multimap::equal_range
        #include <iostream>
        #include <string>
        #include <unordered_map>
        #include <algorithm>
        
        typedef std::unordered_multimap<std::string,std::string> stringmap;
        
        int main ()
        {
          stringmap myumm = {
             {"orange","FL"},
             {"strawberry","LA"},
             {"strawberry","OK"},
             {"pumpkin","NH"}
          };
        
          std::cout << "Entries with strawberry:";
          auto range = myumm.equal_range("strawberry");
          for_each (
            range.first,
            range.second,
            [](stringmap::value_type& x){std::cout << " " << x.second;}
          );
        
          return 0;
        }
        

        请参考链接:http://www.cplusplus.com/reference/unordered_map/unordered_multimap/equal_range/

        【讨论】:

        • @einpoklum 这是答案,删除前请阅读此元数据youre-doing-it-wrong-a-plea-for-sanity-in-the-low-quality-posts-queue
        • 让我重新表述一下(审查机制不允许您制作特定的 cmets,您要从列表中选择):OP 询问“为什么会发生 X?” - 您的回答虽然通常可能有用,但不能解释 OP 的代码会发生什么。所以,不是答案。
        猜你喜欢
        • 2019-06-16
        • 2018-05-26
        • 2020-01-28
        • 2023-01-14
        • 2019-08-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-05
        相关资源
        最近更新 更多