【问题标题】:Insert pair containig non copyable object into map将包含不可复制对象的对插入地图
【发布时间】:2020-06-22 14:31:45
【问题描述】:

鉴于这张地图:

map<string,pair<mutex,set<string>>> m;

如果键中不存在新元素,我想插入它们。我可以使用operator[] 来做到这一点,即:

string possibly_new_key{"foo"};
m[possibly_new_key];

这将默认构造我的pair&lt;mutex,set&gt;,这也是我想要的。问题是我的程序的性能是我第一个也是最后一个关心的问题。出于这个原因,我想使用map::insertmap::emplace_hint 并使用提示(无论如何我必须事先计算)来“如果它不存在则插入”。但我无法弄清楚如何正确调用该函数,因为无论我尝试什么,要么

  1. std::pair 默认构造格式不正确,或者
  2. std::mutex 不可复制,编译失败。

我想要什么(但没用):

auto it=m.lower_bound(possibly_new_key);
//do_stuff_with_it(it);
auto new_value=make_pair(mutex{},set<string>{});
m.emplace_hint(it, piecewise_construct, forward_as_tuple(possibly_new_key), forward_as_tuple(new_value));

有没有办法使用提示来完成此操作,或者只是默认构造新值或提供默认构造的值并移动它?

【问题讨论】:

    标签: c++ stdmap std-pair


    【解决方案1】:

    了解它的工作原理!

    emplace 实际上可以采用空参数来分段默认构造。使用std::forward_as_tuple() 会传递这样一个参数。所以我最终得到的是:

    m.emplace_hint(it, piecewise_construct, forward_as_tuple(possibly_new_key), forward_as_tuple());
    

    这个解决方案首先完成了我想要的一切,它使用一个提示来可能具有摊销的常量复杂性,并且它默认构造适当的映射类型。

    【讨论】:

      【解决方案2】:

      标准容器的所有元素都必须是可复制的。 您可以使用共享指针作为可复制元素:

      struct MutexSetStr
      {
        std::mutex            mutex;
        std::set<std::string> data;
      };
      std::map< std::string, std::shared_ptr<MutexSetStr> > m;
      
      std::shared_ptr<MutexSetStr> new_value(new MutexSetStr);
      new_value.mutex.reset(new std::mutex);
      m[new_key] = new_value; // or any other method to insert
      

      【讨论】:

      • 可复制的或可移动的。另外,比起std::shared_ptr{new ...},更喜欢std::make_shared();大多数用户永远不必写newdelete
      • @underscore_d 可能。其实我的专长是c++03。不要犹豫,提出一个更“新鲜”的答案。 :-p
      • 我的理解是,在现代 c++ 中,对地图中使用的类型没有具体要求(取决于使用的方法),因此我尝试使用 emplace(),因为它的唯一要求应该是一些一种可施工性。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-02
      • 1970-01-01
      相关资源
      最近更新 更多