class Book {
public:
int x;
// string *y;
bool operator<(const Book &rhs) const {
return x < rhs.x;
}
bool operator>(const Book &rhs) const {
return rhs < *this;
}
bool operator<=(const Book &rhs) const {
return !(rhs < *this);
}
bool operator>=(const Book &rhs) const {
return !(*this < rhs);
}
~Book() {
std::cout << ":"
<< "default destructor\n";
}
Book() {
std::cout << ":"
<< "default constructor\n";
}
Book(int n) {
this->x = n;
std::cout << ":"
<< "constructor with parameter\n";
}
Book(Book &&b) {
this->x = b.x;
std::cout << ":"
<< "move constructor\n";
}
Book(const Book &b) {
this->x = b.x;
std::cout << ":"
<< "copy constructor\n";
}
Book &operator=(const Book &b) {
this->x = b.x;
std::cout << ":"
<< "copy assigment\n";
return *this;
}
Book &operator=(Book &&b) {
this->x = b.x;
std::cout << ":"
<< "move assignment\n";
return *this;
}
};
[] 操作符:
示例:
map<int, Book> data;
data[1]=2;
cout<<"###"<<endl;
data[1]=200;
结果:
:constructor with parameter
:default constructor
:move assignment
:default destructor
###
:constructor with parameter
:move assignment
:default destructor
:default destructor
总结:
key不存在时:会先构造一个默认value对象。然后调用赋值运算符,将参数中的value move过去。
key存在时:调用赋值运算符,将参数中的value move过去。
insert:
示例:
map<int, Book> data;
data.insert(make_pair(1,1));
cout<<"###"<<endl;
data.insert(make_pair(1,2));
cout<<data[1].x<<endl;
结果:
:constructor with parameter
###
:constructor with parameter
:default destructor
1
:default destructor
总结:
key不存在时:
在C++11里面,原地构造了一个value
key存在时:
在C++11里面,原地构造了一个value,但并未实际更新容器。
emplace:
map<int, Book> data;
data.emplace(1, 1);
cout<<"###"<<endl;
data.emplace(1, 2);
cout<<data[1].x<<endl;
结果:
:constructor with parameter
###
:constructor with parameter
:default destructor
1
:default destructor
总结:
key不存在时:
在C++11里面,原地构造了一个value
key存在时:
在C++11里面,原地构造了一个value,但并未实际更新容器。
输出与insert一样。实际gcc 中,insert就是用emplace实现的。
try_emplace:
map<int, Book> data;
data.try_emplace(1,1);
data.try_emplace(1,2);
cout<<data[1].x<<endl;
输出:
:constructor with parameter
1
:default destructor
总结:
key不存在时:
在C++11里面,原地构造了一个value
key存在时:
不构造任何value对象。
insert_or_assign:
map<int, Book> data;
data.insert_or_assign(1,1);
cout<<"###"<<endl;
data.insert_or_assign(1,2);
cout<<data[1].x<<endl;
输出:
:constructor with parameter
###
:constructor with parameter
:move assignment
:default destructor
2
:default destructor
总结:
key不存在时:
在C++17里面,原地构造了一个value
key存在时:
更新了value对象。
最后的总结:
如果map中的数据插入后不需要更新,应该选择try_emplace方式。
如果map中的数据随时可能更新,应该选择insert_or_assign方式。(其实全部场合用insert_or_assign 更安全,他本质上是个不构造临时对象的 operator [])
环境:
ubuntu 22.04
gcc 11
-std=c++17