我有一个
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++ 中的“移动”不会删除元素,它只是调用移动构造函数,对于简单类型,它只会复制它们,您可以声明一个移动构造函数来查看它被调用
最后,您无法移动
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&