Moving keys from unordered_map
c++, c++11, move-semantics, unordered-map
Solution
You cannot move, keys will be copied, since
value_type std::pair<const Key, T>
http://en.cppreference.com/w/cpp/container/unordered_map so, here
for (auto &p : map)
`p` will be deduced to `std::pair<const std::string, int>`.
Problem
I've searched but I only found questions about move constructor with the mapped value, but I want to try something different. Is it possible to use `std::move` the key from a `std::unordered_map`? The reason is quite simple: I'd like to construct an example where I create a vector from the map, wasting as little as possible of memory. I know it would mess up with the representation of the map, but hey, after all I will never use the map again, so it would make sense to move values out. My guess is this: no, I cannot do that. However, I'd like some confirmation. Here's a simple code. I expected to see the move constructor called, but I have the copy constructor called. Cheers & Thanks! ``` #include <iostream> #include <unordered_map> #include <vector> #include <string> #include <utility> class prop { public: prop(const std::string &s, int i) : s_(s), i_(i) { std::cout << "COPIED" << std::endl; }; prop(std::string &&s, int i) : s_(std::move(s)), i_(i) { std::cout << "MOVED" << std::endl; }; std::string s_; int i_; }; std::string gen_random(const int len) { static const char alphanum[] = "ABC"; std::string s; s.resize(len); for (int i = 0; i < len; ++i) { s[i] = alphanum[rand() % (sizeof(alphanum) - 1)]; } return s; } int main() { const long n = 3, len = 4, max = 20; std::unordered_map<std::string, int> map; std::cout << ">>GENERATING" << std::endl; for (int i = 0; i < n; i++) map[gen_random(len)]++; if (map.size() < max) { std::cout << ">>MAP" << std::endl; for (auto &p : map) std::cout << p.first << " : " << p.second << std::endl; } std::cout << ">>POPULATING VEC" << std::endl; std::vector<prop> vec; vec.reserve(map.size()); for (auto &p : map) vec.push_back(prop(p.first, p.second)); if (map.size() < max) { std::cout << ">>VEC" << std::endl; for (auto &p : vec) std::cout << p.s_ << " : " << p.i_ << std::endl; std::cout << ">>MAP" << std::endl; for (auto &p : map) std::cout << p.first << " : " << p.second << std::endl; } std::cout << ">>POPULATING MOV" << std::endl; std::vector<prop> mov; mov.reserve(map.size()); for (auto &p : map) mov.push_back(prop(std::move(p.first), p.second)); if (map.size() < max) { std::cout << ">>MOV" << std::endl; for (auto &p : mov) std::cout << p.s_ << " : " << p.i_ << std::endl; std::cout << ">>MAP" << std::endl; for (auto &p : map) std::cout << p.first << " : " << p.second << std::endl; } return 0; } ``` output ``` >>GENERATING >>MAP CBAC : 1 BCAC : 1 BBCC : 1 >>POPULATING VEC COPIED COPIED COPIED >>VEC CBAC : 1 BCAC : 1 BBCC : 1 >>MAP CBAC : 1 BCAC : 1 BBCC : 1 >>POPULATING MOV COPIED COPIED COPIED >>MOV CBAC : 1 BCAC : 1 BBCC : 1 >>MAP CBAC : 1 BCAC : 1 BBCC : 1 Program ended with exit code: 0 ```