将自定义类型对象添加到std :: map时会发生什么?

时间:2015-08-06 12:24:20

标签: c++ dictionary

我无法将foo对象添加到地图myFoos中,直到我发现this answer表示需要默认构造函数。

将对象添加到地图时,我希望将其简单地复制并放置到位,然而,真正发生的是默认构造,赋值和副本。

有人可以解释这种行为吗?

#include <map>

using namespace::std;

class Foo {
public:
  Foo() { }; // Default
  Foo(int id) : _id(id) { }; // Main
  Foo(const Foo& other) { }; // Copy
  Foo operator= (const Foo& other) { _id = other._id; return *this; } // Assign
  int getID() { return _id; }
private:
  int _id;
};

int main()
{
  map<int,Foo> myFoos;
  Foo foo(123);      // Main
  myFoos[123] = foo; // Default, Assign, Copy
}

修改 我最初没有在赋值运算符的函数体中发生任务,并且一些答案正确地指出了这一点。我相应地修改了代码。

2 个答案:

答案 0 :(得分:4)

在完成任何作业和副本之前,代码myFoos[123]需要创建一个Foo,以便在地图中插入密钥123。然后将该值复制或移动到map中,然后返回给您进行进一步操作。

索引运算符返回对映射中元素的引用,如果它不存在,则会创建它并为您插入。如果它已经存在,它只返回对已经存在的那个的引用。

请参阅std::map::operator[]

  

T& operator[]( Key&& key );

     

返回对映射到等效于key的键的值的引用,如果此类键尚不存在则执行插入。

     

如果执行插入,则映射值是值初始化的(默认为类类型构造,否则为零初始化),并返回对它的引用。

  

int id = myFoos[123].getID(); // returns 0 instead of 123

这里的0是因为该类尚未完全实现(默认和复制构造函数以及赋值运算符),因此id在默认构造函数中初始化(在本例中为0)

答案 1 :(得分:3)

operator[]使用默认构造函数初始化指定键的元素,并返回对它的引用。

您的分配操作员省略(有意或无意)分配

_id = other._id

因此,在

myFoos[123] = foo;

默认_id=0未被foo._id替换。