描述:
使用一个map<int,int> m; 可以使用对应的函数插入数据,因为map重载了[]运算符,所以可以通过m[key] = value进行赋值。一般情况,value为默认类型啊,直接使用[]运算符直接操作即可。没什么问题。
当value为自定义类,会出现相关问题,例如:
#include <iostream>
#include <map>
#include <string>
#include <stdio.h>
using namespace std;
class A {
public:
A(){
cout<<"A()"<<",Line:"<<__LINE__<<endl;
}
A(int key,int val): key(key),val(val) {
cout<<"A(int key,int val) = "<<"k="<<key<<"v="<<val<<",Line:"<<__LINE__<<endl;
}
A(const A & a) {
cout<<"A(A & a) =,Line:"<<__LINE__<<endl;
key = a.key;
val = a.val;
}
const A & operator=(const A & a) { //返回引用可以改变左值。
cout<<"A & operator=,Line:"<<__LINE__<<endl;
key = a.key;
val = a.val;
return *this;
}
int key;
int val;
};
int main() {
std::map<int,A> vm = {{1,A(1,1)}};
cout<<"Start vm"<<endl;
// 使用[]时,先调用默认构造,再调用赋值函数,如果没有实现默认构造,编译会报错,错误如下<<...>>
/*
/usr/include/c++/8/tuple:1668:70: 错误:no matching function for call to ‘A::A()’
second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
*/
所示,或者使用insert_or_assign函数.
vm[2] = A(2,2);
cout<<"End vm"<<endl;
return 0;
}
/*
A(int key,int val) = k=1v=1,Line:14
A(A & a) =,Line:17
A(A & a) =,Line:17
Start vm
A(int key,int val) = k=2v=2,Line:14
A(),Line:11
A & operator=,Line:22
End vm
*/
map中value是自定义类型的,直接使用[]进行存储结时,例中value的调用自身方法为先调用{默认无参构函数,再调用赋值函数}
所以,如下使用[]存value,必须在student中实现默认构造,不然编译会出错,如下:
<<
没有默认无参构造函数,直接编译报错失败:(添加默认构造函即可解决该问题)
/usr/include/c++/4.8.2/tuple:1090:70: error: no matching function for call to ‘A::A()’
second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
>>
c++17中,解决了该问题,可以直接使用insert_or_assign()
vm.insert_or_assign(0,A(0,0));
2.使用结构体或者类作为map的key是,需要重载运算符<,不然会就报错,(因为要排序存储,需要自定义对应的排序函数进行判别)
/usr/include/c++/5/bits/stl_function.h:387:20: error: no match for ‘operator<’ (operand types are ‘const Person’ and ‘const Person’)
{ return __x < __y; }
通常使用string直接坐为key,那是因为string重载了运算符<.
正确使用代码:
#include <iostream>
#include <map>
#include <string>
#include <stdio.h>
using namespace std;
class A {
public:
A(){
cout<<"A()"<<",Line:"<<__LINE__<<endl;
}
A(int key,int val): key(key),val(val) {
cout<<"A(int key,int val) = "<<"k="<<key<<"v="<<val<<",Line:"<<__LINE__<<endl;
}
A(const A & a) {
cout<<"A(A & a) =,Line:"<<__LINE__<<endl;
key = a.key;
val = a.val;
}
const A & operator=(const A & a) {
cout<<"A & operator=,Line:"<<__LINE__<<endl;
key = a.key;
val = a.val;
return *this;
}
bool operator< (const A & a) const { // 重载运算符,因为插入map是需要进行当前key值的比较排
return key < a.key || val < a.val;
}
int key;
int val;
};
void display(std::map<A,int> mm){
for(const auto & iter:mm) {
cout<<iter.first.key<<"--"<<iter.first.val<<"--"<<iter.second<<endl;
}
}
int main() {
std::map<A,int> sm;
sm[A(4,5)] = 1;
display(sm);
return 0;
}
输出:
4--5--1
4--6--2