Using C++, if I want to convert a vector
into set
or unordered_set
container, it can be easily done by:
#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;
}
However, the same technique doesn't work for map
or unordered_map
containers. I'm wondering if there is a better way to store all the elements from a vector into map
/ unordered_map
container other than:
for (int ele : vec) {
++uMap[ele];
}
Also, which copy constructor from https://en.cppreference.com/w/cpp/container/unordered_set/unordered_set is called for the code below:
set<int> s(vec.begin(), vec.end());
And why a similar copy constructor from https://en.cppreference.com/w/cpp/container/unordered_map/unordered_map is not available?
Let's look at your set
construction.
vector<int> vec {1, 2, 2, 3, 3, 3, 4, 4, 4, 4}; set<int> s(vec.begin(), vec.end());
This succeeds because the value_type
of your set
is int
. That's not just convenient terminology. A std::set
defines a member type called value_type
, and I am saying that std::set<int>::value_type
is int
. Since dereferencing vec.begin()
gives a value implicitly convertible to int
(well, it is int
), this construction succeeds.
Moving over to map
, there is again a member type called value_type
. This time, though, value_type
is not int
, hence your proposed construction fails. The value_type
of a map
is a pair
containing the key-value pair. That is, std::map<int, size_t>::value_type
is std::pair<const int, size_t>
. Since there is no known conversion from int
to any flavor of std::pair
, your proposed construction fails.
If you had instead worked from a vector
of pair
s, your construction could succeed.
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());
This results in m[1] == 2
, m[2] == 3
, m[3] == 3
, and m[4] == 4
. The extra {4,4}
is dropped because this is a map
, not a multimap
. (It is unspecified whether the first or second {4,4}
is dropped, but whichever is dropped is the extra one.)