排序std :: unordered_map <std :: string,std :: atomic <unsigned =“”int =“”>&gt;按价值观

时间:2018-06-09 12:51:54

标签: c++ c++17

我已经std::unordered_map<std::string, std::atomic<unsigned int>>

我想打印键和值,按值排序。
我遇到的最好的解决方案是创建一个对的向量并对其进行排序

但由于无法复制std::atomic<unsigned int>,最有效的解决方案是什么?

2 个答案:

答案 0 :(得分:5)

将数据副本复制到向量中会有效,但您需要提供一个自定义操作,在load()上调用atomic<unsigned>以使其成为普通unsigned。既然你不得不这样做,你也可以颠倒对中的术语顺序:

std::vector<pair<unsigned int,std::string>> copy;
std::transform(
    m.begin()
,   m.end()
,   back_inserter(copy)
,   [](const pair<const std::string, std::atomic<unsigned int>>& p) {
        return make_pair(p.second.load(), p.first);
    }
);

现在该值是第一个,std::sort的调用不再需要自定义比较器:

std::sort(copy.begin(), copy.end());

Demo.

答案 1 :(得分:0)

另一个解决方案是将unordered_map复制到multimap中,将值作为键,然后将其打印出来:

#include <iostream>
#include <string>
#include <map>
#include <unordered_map>
#include <atomic>
#include <algorithm>
#include <iterator>

int main()
{
    std::unordered_map<std::string, std::atomic<unsigned int>> m;
    for (auto p : std::initializer_list<std::pair<std::string, unsigned int>>{{ "a", 32},{ "b" , 22 },{ "c" , 32 },{ "d" , 22 },{ "e" , 55 } })
        m.emplace(p);

    std::multimap<unsigned int, std::string> printmap;

    std::transform(m.begin(), m.end(), std::inserter(printmap, printmap.end()),
        [](auto const &p) { return std::make_pair(p.second.load(), p.first); });

    for (auto const &p : printmap)
        std::cout << p.first << " - " << p.second << std::endl;

    return 0;
}

演示:https://ideone.com/MgtMY8

22 - d
22 - b
32 - c
32 - a
55 - e