• c++之map使用踩坑


    描述:

           使用一个map m; 可以使用对应的函数插入数据,因为map重载了[]运算符,所以可以通过m[key] = value进行赋值。一般情况,value为默认类型啊,直接使用[]运算符直接操作即可。没什么问题。

     当value为自定义类,会出现相关问题,例如:

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. class A {
    7. public:
    8. A(){
    9. cout<<"A()"<<",Line:"<<__LINE__<
    10. }
    11. A(int key,int val): key(key),val(val) {
    12. cout<<"A(int key,int val) = "<<"k="<"v="<",Line:"<<__LINE__<
    13. }
    14. A(const A & a) {
    15. cout<<"A(A & a) =,Line:"<<__LINE__<
    16. key = a.key;
    17. val = a.val;
    18. }
    19. const A & operator=(const A & a) {
    20. cout<<"A & operator=,Line:"<<__LINE__<
    21. key = a.key;
    22. val = a.val;
    23. return *this;
    24. }
    25. int key;
    26. int val;
    27. };
    28. int main() {
    29. std::map<int,A> vm = {{1,A(1,1)}};
    30.   cout<<"Start vm"<
    31.   // 使用[]时,先调用默认构造,再调用赋值函数,如果没有实现默认构造,编译会报错,错误如上<<...>>所示,或者使用insert_or_assign函数.
    32.   vm[2] = A(2,2);   
    33.   cout<<"End vm"<
    34. return 0;
    35. }
    1. /*
    2. A(int key,int val) = k=1v=1,Line:14
    3. A(A & a) =,Line:17
    4. A(A & a) =,Line:17
    5. Start vm
    6. A(int key,int val) = k=2v=2,Line:14
    7. A(),Line:11
    8. A & operator=,Line:22
    9. End vm
    10. */

        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是,需要重载运算符<,不然会就报错,

    1. /usr/include/c++/5/bits/stl_function.h:387:20: error: no match foroperator<’ (operand types are ‘const Person’ andconst Person’)
    2. { return __x < __y; }

    通常使用string直接坐为key,那是因为string重载了运算符<. 

    正确使用代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. class A {
    7. public:
    8. A(){
    9. cout<<"A()"<<",Line:"<<__LINE__<
    10. }
    11. A(int key,int val): key(key),val(val) {
    12. cout<<"A(int key,int val) = "<<"k="<"v="<",Line:"<<__LINE__<
    13. }
    14. A(const A & a) {
    15. cout<<"A(A & a) =,Line:"<<__LINE__<
    16. key = a.key;
    17. val = a.val;
    18. }
    19. const A & operator=(const A & a) {
    20. cout<<"A & operator=,Line:"<<__LINE__<
    21. key = a.key;
    22. val = a.val;
    23. return *this;
    24. }
    25. bool operator< (const A & a) const { // 重载运算符,因为插入map是需要进行当前key值的比较排
    26. return key < a.key || val < a.val;
    27. }
    28. int key;
    29. int val;
    30. };
    31. void display(std::mapint> mm){
    32. for(const auto & iter:mm) {
    33. cout<"--"<"--"<
    34. }
    35. }
    36. int main() {
    37. std::mapint> sm;
    38. sm[A(4,5)] = 1;
    39. display(sm);
    40. return 0;
    41. }
    42. 输出:
    43. 4--5--1
    44. 4--6--2


      

  • 相关阅读:
    网卡中断对cpu的不同绑定方式对Redis性能的影响
    (十)笔记.net学习Lambda和Linq表达式
    java基础-第4章-面向对象(二)
    编译原理期末复习
    2022-09-28 Android APP 用interface 接口的形式对jni进行回调,实例测试
    PTA初级题目练习
    机器学习方法之k近邻方法的综述
    【光学】Matlab实现色散曲线拟合
    NANK南卡再出力作,搭载全新蓝牙5.3芯片半入耳式南卡小音舱正式发售!
    【AIGC】图片生成的原理与应用
  • 原文地址:https://blog.csdn.net/qq_26105397/article/details/126252100