Search code examples
c++vectormoveunordered-map

C++ move(): what's left in the vector?


I have a piece of code, where in vector, elements are pairs of int and string. Then I want to move all elements from vector into an unordered_map<int, string>:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <unordered_map>
#include <vector>
using namespace std;

template <typename C>
void print(const C& container) {
    for (const auto& ele : container) {
        cout << "(" << ele.first << ", " << ele.second << "), ";
    }
    cout << endl;
}

int main() {
    vector<pair<int, string>> v {
        {1, "one"},
        {2, "two"},
        {3, "three"},
        {4, "four"},
        {5, "five"}
    };
    unordered_map<int, string> uMap;

    move(begin(v), end(v), inserter(uMap, begin(uMap)));

    cout << "In unordered_map:" << endl;
    print(uMap);
    cout << endl << "In vector:" << endl;
    print(v);

    return 0;
}

What I don't understand is the results:

In unordered_map:
(5, five), (4, four), (3, three), (2, two), (1, one), 
In vector:
(1, ), (2, ), (3, ), (4, ), (5, ),

Why are those integers left in vector? I thought move() function will move all the elements from vector into unordered_map, so that nothing will be left in the vector?


Solution

  • From cppreference:

    Moves the elements in the range [first, last), to another range beginning at d_first, starting from first and proceeding to last - 1. After this operation the elements in the moved-from range will still contain valid values of the appropriate type, but not necessarily the same values as before the move.

    Because the algorithm is working on iterators, there is no way it could actually remove elements from the vector. They are still there and they can have the same value as before (but not necessarily).

    Also the strings are still present in the vector. After moving from a std::string it is in a valid but unspecified state. In this case the strings are empty.