Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to move elements from std::map to std::vector

I have a std::map which contains a bunch of key value pairs. I want move these elements into a std::vector. I tried using std::transform from <algorithm> to do this, but it doesn't work. Here's my code:

#include <algorithm>
#include <cstdint>
#include <iostream>
#include <map>
#include <vector>

struct Values
{
        uint32_t a = 0;
        uint32_t b = 0;

        Values(uint32_t x, uint32_t y): a(x), b(y) {}
};

template <typename MapType>
auto foo(MapType&& map)
{
        std::vector<typename MapType::value_type> v;
        v.reserve(map.size());

        std::transform(map.begin(), map.end(), std::back_inserter(v), [](const auto& kv) -> decltype(auto) { return std::move(kv); });
        std::cout << map.size() << " " << v.size() << "\n";
}

int main()
{
        std::map<uint32_t, Values> data;
        for(uint32_t i = 0; i < 100; i++)
                data.emplace(std::piecewise_construct, std::forward_as_tuple(i), std::forward_as_tuple(2*i, 3*i));

        foo(std::move(data));

        return 0;
}

I'm compiling this code using gcc:

g++ -std=c++23 -Ofast -Wall -Wextra -Wpedantic -Wconversion -Werror main.cpp

Here's the link to compiler explorer.

The program outputs the number of elements in the std::map and std::vector after the call to std::transform. The output that I get is:

100 100

This tells me that instead of the elements being moved, they we just copied into the vector. How can I change this code to use move instead.

like image 698
Setu Avatar asked May 31 '26 04:05

Setu


1 Answers

You can get close with something like this:

for (auto it = map.begin(); it != map.end(); /*no increment*/) {
  auto node = map.extract(it++);
  v.emplace_back(std::move(node.key()), std::move(node.mapped()));
}

This should involve only move constructors on both key and value objects, and no copy constructors (for those classes where the two are distinct, of course; in your example, moving and copying are equivalent). It will leave the map empty at the end.

like image 178
Igor Tandetnik Avatar answered Jun 01 '26 18:06

Igor Tandetnik



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!