从不同的容器中移动构造函数 `std::map`
Move contruct `std::map` from a different container
我想将临时容器转换为 std::map<S, T>
。
假设临时容器是 std::unordered_map<S, T>
,T
可移动构造。
我的问题是:(如何)我可以使用 std::map<S, T>
的移动构造函数?
对于简化的情况,请考虑
#include <bits/stdc++.h>
using namespace std;
template<typename S, typename T>
map<S, T>
convert(unordered_map<S, T> u)
{
// Question: (how) can I use move constructor here?
map<S, T> m(u.begin(), u.end());
return m;
}
int main()
{
unordered_map<int, int> u;
u[5] = 6;
u[3] = 4;
u[7] = 8;
map<int, int> m = convert(u);
for (auto kv : m)
cout << kv.first << " : " << kv.second << endl;
return 0;
}
输出为
3 : 4
5 : 6
7 : 8
当然,在更复杂的设置中,S
和T
不是int
。
非常感谢。
更新 感谢大家的及时回复!我很欣赏 map
在数据结构上与 unordered_map
本质上不同的观察结果。因此,如果移动不能发生在容器级别,我也会接受元素级别的移动。只是想确定并知道如何做。
不,您不能从 std::unordered_map<S, T>
.
移动构造 std::map<S, T>
Let's say the temporary container is a std::unordered_map, with T move-constructible.
如果您希望移动您的值,其类型是可移动的T
,而不是复制-ing,尝试使用 std::move_iterator
如下:
map<S, T> m(std::make_move_iterator(u.begin()), std::make_move_iterator(u.end()));
例子
#include <iostream>
#include <map>
#include <unordered_map>
#include <iterator>
struct S
{
bool init = true;
static int count;
S() { std::cout << "S::S() " << ++count << "\n"; }
S(S const&) { std::cout << "S::S(S const&)\n"; }
S(S&& s) { std::cout << "S::S(S&&)\n"; s.init = false; }
~S() { std::cout << "S::~S() (init=" << init << ")\n"; }
};
int S::count;
int main()
{
std::cout << "Building unordered map\n";
std::unordered_map<int, S> um;
for (int i = 0; i < 5; ++i)
um.insert(std::make_pair(i, S()));
std::cout << "Building ordered map\n";
std::map<int, S> m(
std::make_move_iterator(um.begin()),
std::make_move_iterator(um.end()));
}
输出
Building unordered map
S::S() 1
S::S(S&&)
S::S(S&&)
S::~S() (init=0)
S::~S() (init=0)
S::S() 2
S::S(S&&)
S::S(S&&)
S::~S() (init=0)
S::~S() (init=0)
S::S() 3
S::S(S&&)
S::S(S&&)
S::~S() (init=0)
S::~S() (init=0)
S::S() 4
S::S(S&&)
S::S(S&&)
S::~S() (init=0)
S::~S() (init=0)
S::S() 5
S::S(S&&)
S::S(S&&)
S::~S() (init=0)
S::~S() (init=0)
Building ordered map
S::S(S&&)
S::S(S&&)
S::S(S&&)
S::S(S&&)
S::S(S&&)
S::~S() (init=1)
S::~S() (init=1)
S::~S() (init=1)
S::~S() (init=1)
S::~S() (init=1)
S::~S() (init=0)
S::~S() (init=0)
S::~S() (init=0)
S::~S() (init=0)
S::~S() (init=0)
我想将临时容器转换为 std::map<S, T>
。
假设临时容器是 std::unordered_map<S, T>
,T
可移动构造。
我的问题是:(如何)我可以使用 std::map<S, T>
的移动构造函数?
对于简化的情况,请考虑
#include <bits/stdc++.h>
using namespace std;
template<typename S, typename T>
map<S, T>
convert(unordered_map<S, T> u)
{
// Question: (how) can I use move constructor here?
map<S, T> m(u.begin(), u.end());
return m;
}
int main()
{
unordered_map<int, int> u;
u[5] = 6;
u[3] = 4;
u[7] = 8;
map<int, int> m = convert(u);
for (auto kv : m)
cout << kv.first << " : " << kv.second << endl;
return 0;
}
输出为
3 : 4
5 : 6
7 : 8
当然,在更复杂的设置中,S
和T
不是int
。
非常感谢。
更新 感谢大家的及时回复!我很欣赏 map
在数据结构上与 unordered_map
本质上不同的观察结果。因此,如果移动不能发生在容器级别,我也会接受元素级别的移动。只是想确定并知道如何做。
不,您不能从 std::unordered_map<S, T>
.
std::map<S, T>
Let's say the temporary container is a std::unordered_map, with T move-constructible.
如果您希望移动您的值,其类型是可移动的T
,而不是复制-ing,尝试使用 std::move_iterator
如下:
map<S, T> m(std::make_move_iterator(u.begin()), std::make_move_iterator(u.end()));
例子
#include <iostream>
#include <map>
#include <unordered_map>
#include <iterator>
struct S
{
bool init = true;
static int count;
S() { std::cout << "S::S() " << ++count << "\n"; }
S(S const&) { std::cout << "S::S(S const&)\n"; }
S(S&& s) { std::cout << "S::S(S&&)\n"; s.init = false; }
~S() { std::cout << "S::~S() (init=" << init << ")\n"; }
};
int S::count;
int main()
{
std::cout << "Building unordered map\n";
std::unordered_map<int, S> um;
for (int i = 0; i < 5; ++i)
um.insert(std::make_pair(i, S()));
std::cout << "Building ordered map\n";
std::map<int, S> m(
std::make_move_iterator(um.begin()),
std::make_move_iterator(um.end()));
}
输出
Building unordered map
S::S() 1
S::S(S&&)
S::S(S&&)
S::~S() (init=0)
S::~S() (init=0)
S::S() 2
S::S(S&&)
S::S(S&&)
S::~S() (init=0)
S::~S() (init=0)
S::S() 3
S::S(S&&)
S::S(S&&)
S::~S() (init=0)
S::~S() (init=0)
S::S() 4
S::S(S&&)
S::S(S&&)
S::~S() (init=0)
S::~S() (init=0)
S::S() 5
S::S(S&&)
S::S(S&&)
S::~S() (init=0)
S::~S() (init=0)
Building ordered map
S::S(S&&)
S::S(S&&)
S::S(S&&)
S::S(S&&)
S::S(S&&)
S::~S() (init=1)
S::~S() (init=1)
S::~S() (init=1)
S::~S() (init=1)
S::~S() (init=1)
S::~S() (init=0)
S::~S() (init=0)
S::~S() (init=0)
S::~S() (init=0)
S::~S() (init=0)