从另一个容器中移动结构`std :: map`

时间:2018-10-15 05:25:34

标签: c++ move-semantics

我想将临时容器转换为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

当然,在更复杂的设置中,ST不是int

非常感谢您。

更新:谢谢大家的及时宝贵的回复!我很欣赏mapunordered_map在数据结构上本质上不同的发现。因此,如果移动不能在容器级别发生,我也将接受元素级别的移动。只是想确定并知道如何做。

2 个答案:

答案 0 :(得分:14)

  

比方说,临时容器是std :: unordered_map,具有T move-constructible。

如果您想移动您的,其类型是可移动的T,而不是复制 -ing,请尝试使用{ {1}}如下:

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()));
}

答案 1 :(得分:0)

否,您无法从std::map<S, T>中移动构建std::unordered_map<S, T>