将自定义类型对象添加到std::map时会发生什么?
What happens when adding custom type objects to std::map?
我在将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
取代
相关文章:
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?
- map<string, int> m= {}; 在C++中是什么意思?
- 创建可以遍历 std::map 值的通用模板迭代器的最简单方法是什么?
- 什么是 Direct3D 12.0 上的"Map Default Buffer"?
- freq_table[field_pm_value] = map<string, int>(); 是什么意思?
- map<int,int>的*迭代器是什么?它不是pair<int,int>
- 方括号在"map <string, int> instance[numberFeatures];"中是什么意思
- 将强制转换运算符重载到 std::map 的正确语法是什么
- 在内存使用方面,c++ 中的 map 和 unordered_map 之间有什么区别吗?
- 什么是 Python 的 map(int,input().split()) 的 C++ 等价物
- 什么算作 std::map 的"write"?
- 这些会做什么(映射[x] [y] = 2;,map [x] [y] = 3;,以及map [x] [y] = 4;在下面
- STD :: MAP的基础结构是什么
- 访问std::map中元素的最有效方法是什么
- 添加和初始化新std::map元素的最有效方法是什么
- template_hint在map中有什么用途
- 有什么理由在 C++17 中使用 std::map::emplace() 而不是 try_emplace() 吗?
- g++ 命令中".map"文件有什么用?
- std::set 和 std::map 有什么区别
- C# 在<map>C++中相当于什么?