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

What happens when adding custom type objects to std::map?

本文关键字:什么 map 对象 类型 添加 std 自定义      更新时间:2023-10-16

我在将foo对象添加到映射myFoos时遇到了麻烦,直到我找到了需要默认构造函数的答案。

当将对象添加到映射中时,我期望它被简单地复制并放置到位,然而,实际发生的是默认构造,赋值和复制。

有人能解释一下这种行为吗?
#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
}
编辑:

我最初在赋值操作符的函数体中没有赋值,一些答案正确地指出了这一点。我相应地修改了代码

在完成任何赋值和复制之前,代码myFoos[123]需要创建一个Foo以插入到键123的映射中。然后将该值复制或移动到map中,然后返回给您以供进一步操作。

索引操作符返回对映射中元素的引用,如果该元素不存在,则创建该元素并为您插入。如果它已经存在,它只返回对已经存在的对象的引用。

参见std::map::operator[]

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

返回对对应于key键的值的引用,如果该键不存在则执行插入操作。

如果执行插入操作,则映射值为value-initialized(对于类类型为默认构造,否则为zero-initialized),并返回对该映射值的引用。


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

这里的0是因为类还没有完全实现(默认和复制构造函数,以及赋值操作符),所以id在默认构造函数中被初始化(在本例中为0)。

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

您的赋值操作符省略了(有意或无意)赋值

_id = other._id

因此,

myFoos[123] = foo;

默认的_id=0不被foo._id取代