首页 > 解决方案 > C++ 将所有元素从向量复制到 map / unordered_map 的最佳方法

问题描述

使用 C++,如果我想将 a 转换vectorset容器unordered_set,可以通过以下方式轻松完成:

#include <iostream>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

int main() {
    vector<int> vec {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};

    // pass
    unordered_set<int> uSet(vec.begin(), vec.end());
    // pass
    set<int> s(vec.begin(), vec.end());
    // fail
    unordered_map<int, size_t> uMap(vec.begin(), vec.end());
    // fail
    map<int, size_t> m(vec.begin(), vec.end());

    return 0;
}

map但是,相同的技术不适用于unordered_map容器。我想知道是否有更好的方法将向量中的所有元素存储到map/unordered_map容器中,而不是:

for (int ele : vec) {
    ++uMap[ele];
}

此外,以下代码调用了来自https://en.cppreference.com/w/cpp/container/unordered_set/unordered_set的复制构造函数:

set<int> s(vec.begin(), vec.end()); 

为什么来自https://en.cppreference.com/w/cpp/container/unordered_map/unordered_map的类似复制构造函数不可用?

标签: c++setunordered-mapunordered-set

解决方案


让我们看看你的set建筑。

vector<int> vec {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};

set<int> s(vec.begin(), vec.end());

这成功了,因为value_type你的setis int。这不仅仅是方便的术语。Astd::set定义了一个名为的成员类型value_type,我说的std::set<int>::value_typeint。由于取消引用vec.begin()提供了一个可隐式转换为int(嗯,它 int)的值,因此此构造成功。

移动到map,再次有一个成员类型称为value_type. 但是,这一次value_type不是int,因此您建议的构造失败。a的value_typeamappair包含键值对的 a。也就是说,std::map<int, size_t>::value_typestd::pair<const int, size_t>。由于没有从int到 的任何风格的已知转换std::pair,因此您建议的构造失败。

如果您改为从 a vectorof pairs 开始工作,则您的构造可能会成功。

vector<pair<const int, size_t>> vecp { {1, 2}, {2, 3}, {3, 3}, {4, 4}, {4, 4} };

map<int, size_t> m(vecp.begin(), vecp.end());

这导致m[1] == 2m[2] == 3m[3] == 3m[4] == 4。多余{4,4}的被删除,因为这是 a map,而不是 a multimap。(未指定第一个或第二个{4,4}是否被丢弃,但无论哪个被丢弃都是额外的。)


推荐阅读