【问题标题】:Can I assign a value to the element pointed at by the iterator returned by map::emplace?我可以为 map::emplace 返回的迭代器指向的元素赋值吗?
【发布时间】:2015-03-03 01:19:55
【问题描述】:

map::emplace 返回一个pair<iterator,bool>

23.2.3 序列容器第 11 段的 C++ 标准(我认为这是编号方案,无论如何,在 2014 年 11 月草案的第 755 页顶部附近)提到了 emplace:

a.emplace(p. args) 返回的迭代器指向新的 从args 构造成a 的元素。

然后在第 760 页的关联容器的表 102 中,它提到了 a_uniq.emplace(args)

pair的迭代器组件指向带有key的元素 相当于t的key。

所以我用“指向元素”来表示它,你知道,指向地图中的元素,并且你可以通过赋值覆盖地图中的值。 (还有键,这可能会破坏地图。)因为如果他们不希望您这样做,则返回值对的第一个元素将是const_iterator,而不是iterator,对吧?

但并非如此。下面的代码(也可以在ideone 看到)表明,无论你分配什么,它都不是映射中的值:

#include <map>
#include <stdio.h>


struct st
{
    int a;
    int b;

    st(int aa = 0, int bb = 0) : a(aa), b(bb) { }
};

void verify(std::string msg, std::map<int,st>& m, int key, int a, int b)
{
    const st st = m[key];
    if (st.a == a && st.b == b)
    {
        printf("ok  %s: a == %d, b == %d\n", msg.c_str(), st.a, st.b);
    }
    else
    {
        printf("*** %s: a == %d (not %d), b == %d (not %d)\n", msg.c_str(), st.a, a, st.b, b);
    }
}

int main(void)
{
    std::map<int,st> a_map;

    st st11(1,1);
    st st35(3,5);

    a_map[9] = st11;
    verify("m9 {1,1}", a_map, 9, 1, 1);

    auto r = a_map.emplace(9, st35);

    printf("emplace {3,5} at 9: %s\n", r.second ? "inserted" : "existing");
    verify("m9 {1,1}", a_map, 9, 1, 1);

    auto pr = *r.first;
    pr.second = st35;

    verify("m9 {3,5}", a_map, 9, 3, 5);

    return 0;
}

为 VC++ 2012 和 gcc-4.9.2 输出以下内容:

ok  m9 {1,1}: a == 1, b == 1
emplace {3,5} at 9: existing
ok  m9 {1,1}: a == 1, b == 1
*** m9 {3,5}: a == 1 (not 3), b == 1 (not 5)

所以显然迭代器并没有指向实际映射结构中的元素。

我在标准(或示例代码等)中误解了什么?

【问题讨论】:

  • auto pr = *r.first; 复制一份。

标签: c++11


【解决方案1】:

这会创建元素的副本:

auto pr = *r.first;

试试这样的:

auto pr = r.first;
pr->second = st35;

或者使用参考

auto &pr = *r.first;

【讨论】:

  • 你知道,这种语法的例子肯定很少。 cppreference 和 cplusplus 都没有使用 emplace 的返回值的例子。 MSDN 有一个从返回值读取但不分配给它的示例。各种谷歌搜索和 SO 搜索也没有提出任何结果。一定不是很受欢迎的功能!
猜你喜欢
  • 1970-01-01
  • 2016-09-18
  • 1970-01-01
  • 2011-01-03
  • 2015-06-17
  • 2019-09-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多