如何将元素从 std::map 移动到 std::vector

问题描述 投票:0回答:1

我有一个

std::map
,其中包含一堆键值对。我想将这些元素移动到
std::vector
中。我尝试使用
std::transform
中的
<algorithm>
来执行此操作,但它不起作用。这是我的代码:

#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;
}

我正在使用

gcc
编译此代码:

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

这是编译器资源管理器的链接。

程序在调用

std::map
后输出
std::vector
std::transform
中的元素数量。我得到的输出是:

100 100

这告诉我,我们只是将元素复制到向量中,而不是移动元素。我如何更改此代码以使用 move 代替。

c++ c++11 move stdmap
1个回答
1
投票

C++ 中的“移动”不会删除元素,它只是调用移动构造函数,对于简单类型,它只会复制它们,您可以声明一个移动构造函数来查看它被调用

最后,您无法移动

const
物体,因此
const auto& kv
需要更改为
auto& kv

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

struct Values
{
    uint32_t a = 0;
    uint32_t b = 0;
    Values(const Values&) { std::cout << "copied!\n"; }
    Values(Values&&) { std::cout << "moved!\n"; }
    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), [](auto& kv) -> decltype(auto) { return std::move(kv); });
    map.clear(); // clear map content which has been "moved from"
    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;
}

您将看到 100

moved
印有
auto&
和 100
copied
印有
const auto&

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.