【问题标题】:Emplacing vector into map将向量放入地图
【发布时间】:2015-02-27 17:15:05
【问题描述】:

鉴于这种类型:

std::map<int, std::vector<T>> map;

如何直接放置元素?

map.emplace(10, /* ? */);

我可以通过先单独创建向量,然后在调用 emplace 时使用该标识符来做到这一点,但如果可以以某种方式直接做到这一点,这是不可取的。

【问题讨论】:

标签: c++ dictionary vector


【解决方案1】:

两者

map.emplace(typename decltype(map)::value_type(10, {1, 2, 3}));

map.emplace(10, std::initializer_list<int>{1, 2, 3});

应该可以正常工作。

我确信 gcc 拒绝我的第一次尝试是有原因的:

map.emplace(10, {1, 2, 3});

但我不知道这是一个好的理由还是一个缺陷。

编辑:这似乎与花括号初始化列表 ({1, 2, 3}) 没有类型有关,因此无法与完美转发一起使用(这对于map.emplace)。关于这一点有几个相关的 SO 帖子,例如this answer

【讨论】:

  • 我认为这是因为emplace 有很多魔法可以使“重载”工作,因此它无法正确推断类型。
  • @MooingDuck:是的,我也这么认为。问题是它是否是 gcc 中的错误或与 gcc 捆绑在一起的标准库,或者标准是否允许。我的 clang 安装似乎失败了,所以我无法测试。
  • @MooingDuck:谢谢。根据stackoverflow.com/a/28634397/1566221,问题是大括号初始化列表不能完美转发。
  • 另外值得注意的是map.insert没有这个问题。
  • @MooingDuck:这增加了与转发有关的说法的可信度。 map.insert 不需要转发,所以它可以让 std::vector 构造一个隐式转换。
【解决方案2】:

piecewise_constructstd::make_tuple 一起使用:

map.emplace(std::piecewise_construct, std::make_tuple(5), std::make_tuple(10, 3));

【讨论】:

  • 永远不要说 C++ 不直观,或者它让你的计算机程序难以阅读。 :droll:
  • 很明显,其意图是用一个包含 10 个元素的向量来初始化 map[5],每个元素都初始化为 3。对吗?
  • 我收回我所说的直接安置它更可取的说法。
  • 此示例不包括何时要将原始指针传递给向量。它应该:)
猜你喜欢
  • 2020-02-27
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多