【问题标题】:Swapping vs. assigning with std::map [] operator (const issue)使用 std::map [] 运算符交换与分配(常量问题)
【发布时间】:2012-08-03 03:24:00
【问题描述】:

我目前在 std::map 上使用 [] 运算符:

map[key] = value;

没什么太疯狂的。但是,我的值包含一个 const 公共成员:

class Value
{
public:
    Value(int input) : member(input) { }
    const int member;
};

在不深入了解我的应用程序的细节的情况下,我们想要保留 const 成员。鉴于此,我假设 map[key] = value 正在做一些事情,例如首先删除现有值,然后插入新值:

map.erase(map.find(key));
map.insert(make_pair(key, value));

但是,实际上似乎正在发生的是operator [] 返回对值的引用,因此尝试使用 = 赋值或移动运算符或其他东西。显然,这是行不通的,因为无法重新分配成员。现在,我可以调用 erase 然后插入自己,但我想知道是否有一种方法可以使用这种“交换”技术来实现 map[key] = value

【问题讨论】:

  • 我不明白为什么这不起作用。地图是如何定义的?
  • 为什么 map[] 不返回引用?这对我来说似乎更直观。
  • 我并不是说它不应该返回一个引用,我对这个实现很满意,我只是在问是否有办法做我所要求的。让我以更简单的方式问这个问题:如果我制作 std::map 类型的映射,则 [] 永远无法工作(由于返回引用)。

标签: c++ dictionary std stdmap c++-standard-library


【解决方案1】:

在 C++ 中实现这样的地图并不容易。想一想:为了做到这一点,您必须让 map[] 返回一个带有重载赋值运算符的代理对象,然后在底层映射上调用擦除和删除,同时还要小心确保它仍然充当引用用作右值时的值。返回引用是唯一明智的做事方式,也更直观。

至于如何做你想做的事,你可能应该只写一个函数来做,然后调用这个函数,而不是尝试直接将元素分配给地图。

【讨论】:

  • 是的,事实上我注意到一个更简单的问问题的方法是“我如何将 operator[] 与 std::map 一起使用”,我想答案是“你不能”。我的困惑来自 ObjC 世界,其中 blah[key] = value 被编译器重写为 [blah insertObject:atKeyedIndex:] (这显然允许交换“魔法”)。
【解决方案2】:

我想您将地图定义为:

std::map<Key, Value> mymap;

请注意,地图的内部节点存储您最初传递的 Key 和 Value 的副本。如果你想使用交换语义,你应该使用指向 Value 的指针,比如:

std::map<Key, std::shared_ptr<Value> > mymap;

然后更改值将类似于:

mymap[key].reset(new Value(...));

【讨论】:

    猜你喜欢
    • 2011-03-03
    • 2014-07-13
    • 1970-01-01
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    • 2014-11-04
    相关资源
    最近更新 更多