• 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


      

  • 相关阅读:
    【5】c++11新特性(稳定性和兼容性)—>override关键字
    JNDIExploit-1.2-SNAPSHOT.jar工具在log4j漏洞复现中的使用
    基于C++11封装的线程池
    同态加密库Seal库的安装(win11+VS2022)
    WordPress 常规设置页面调用媒体中心上传图片插入URL(新版可用)
    高性能网络编程 - 关于单台服务器并发TCP连接数理论值的讨论
    angr原理与实践(二)—— 各类图的生成(CFG CG ACFG DDG等)
    JavsScript系列-Promise的错误捕获
    机器学习理论基础—支持向量机的推导(一)
    【Rust】6、练习:自己实现 ls
  • 原文地址:https://blog.csdn.net/qq_26105397/article/details/126252100