【问题标题】:Can I create an unordered_map of string and atomic<int> key-value pairs?我可以创建字符串和 atomic<int> 键值对的 unordered_map 吗?
【发布时间】:2017-09-04 01:47:00
【问题描述】:

我想创建一个unordered_map&lt;string, atomic&lt;int&gt;&gt;。我将使用它来增加(fetch_add)、存储或加载基于字符串(键)的原子值。例如,假设我有 10 个原子整数计数器,但我只想获取 4 或它们的值。我想要一个看起来像这样的unordered_map

unordered_map<string, atomic<int>> myValues = {
    {"first", atomic<int>(0)},
    {"second", atomic<int>(0)}, ... the last key being "tenth"}
};

然后说我有一个字符串向量

vector<string> wanted = {"first", "third", "tenth"};

我想做以下事情:

for (auto want: wanted) {
    cout <<  myValues[want].load() << endl;

这应该打印出想要的键的值。

我可以这样做吗?如果我尝试像上面那样创建映射,我会收到错误消息,指出 atomic 的赋值运算符被删除?有没有办法做到这一点?

【问题讨论】:

  • atomic 类型既不可复制也不可移动
  • 这意味着我的方法是 DOA?有没有不同的方法来完成同样的事情?
  • 您可以单独定义初始化数据,然后在地图中循环遍历它和emplace,而不是尝试复制atomic 值。
  • @Alf,你能给我举个简单的例子吗?

标签: c++ c++11 atomic unordered-map


【解决方案1】:

当然,可以创建unordered_map&lt;string, atomic&lt;int&gt;&gt;,但您不能使用initializer_list 构造函数对其进行初始化,因为atomic&lt;T&gt; 对象既不可移动也不可复制。

由于地图中的值可以使用单个参数构造,因此您可以使用emplace 成员函数。

std::unordered_map<std::string, std::atomic<int>> m;

for(auto const& key : {"first", "second", "third", "fourth"})
    m.emplace(key, 0);

如果您的键/值类型构造函数采用多个参数,为避免复制和移动,您必须使用std::pairpiecewise construction constructoremplace 成员函数。

for(auto const& key : {"first", "second", "third", "fourth"})
    m.emplace(std::piecewise_construct,
              std::forward_as_tuple(key),
              std::forward_as_tuple(0));

如果您的编译器支持 C++17,并且可以使用单个参数构造键类型,那么您还可以使用不太冗长的 try_emplace 成员函数

for(auto const& key : {"fifth", "sixth", "seventh", "eight"})
    m.try_emplace(key, 0);

【讨论】:

  • 为什么是try_emplacem.emplace(key, 0); 很好(不支持 C++17)
  • @LWimsey 好吧,那不是很傻吗?显然是多虑了。现已修复。
猜你喜欢
  • 2012-10-15
  • 2013-03-21
  • 2019-07-24
  • 1970-01-01
  • 2020-11-28
  • 2021-11-13
  • 2021-03-10
  • 2021-12-29
  • 1970-01-01
相关资源
最近更新 更多