首页 > 其他分享 >std::sort 传入成员函数指针报错的解决方案

std::sort 传入成员函数指针报错的解决方案

时间:2023-11-06 09:13:14浏览次数:59  
标签:std sort int pos vector 报错 __ bool cmp

问题引入

有一个类 A,A 的某个成员函数需要对 A 的某些变量进行 std::sort,同时要调用 A 的另一个成员函数作为比较器。如代码所示:

struct A {
  vector<int> pos = {0, 4, 2, 5, 3};
  bool cmp(int x, int y) { return pos[x] < pos[y]; }
  void demo() {
    vector<int> a = {2, 3, 1, 0, 4};
    sort(a.begin(), a.end(), cmp);
    for (int x : a) printf("%d\n", x);
  }
};

希望以 A::cmp 作为比较器对 vector<int> a 排序。

编译错误:(关键的一段)

error: must use '.*' or '->*' to call pointer-to-member function in '((__gnu_cxx::__ops::_Iter_comp_iter<bool (A::*)(int, int)>*)this)->__gnu_cxx::__ops::_Iter_comp_iter<bool (A::*)(int, int)>::_M_comp (...)', e.g. '(... ->* ((__gnu_cxx::__ops::_Iter_comp_iter<bool (A::*)(int, int)>*)this)->__gnu_cxx::__ops::_Iter_comp_iter<bool (A::*)(int, int)>::_M_comp) (...)'
         { return bool(_M_comp(*__it1, *__it2)); }
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

解决方案一:lambda functions

struct B {
  vector<int> pos = {0, 4, 2, 5, 3};
  void demo() {
    vector<int> a = {2, 3, 1, 0, 4};
    sort(a.begin(), a.end(), [&](int x, int y) { return pos[x] < pos[y]; });
    for (int x : a) printf("%d ", x);
  }
};

直接使用 lambda 函数,引用捕获 this->pos 进行访问。关于 lambda 函数的更多说明参见 https://zh.cppreference.com/w/cpp/language/lambda

解决方案二:static members

struct C {
  vector<int> pos = {0, 4, 2, 5, 3};
  static bool cmp(int x, int y) { return x < y; }
  void demo() {
    vector<int> a = {2, 3, 1, 0, 4};
    sort(a.begin(), a.end(), cmp);
    for (int x : a) printf("%d ", x);
  }
};

bool cmp(int, int) 声明为 static,也就是静态成员函数。静态成员函数不和任意一个对象绑定,它是静态的,它是静态区域的函数,可以使用 A::cmp 或者 a.cmp 调用。静态成员函数不能访问类中的变量。关于 static 的更多说明参见 https://zh.cppreference.com/w/cpp/language/static

解决方案三:std::bind

struct D {
  vector<int> pos = {0, 4, 2, 5, 3};
  bool cmp(int x, int y) { return pos[x] < pos[y]; }
  void demo() {
    using namespace placeholders;
    vector<int> a = {2, 3, 1, 5, 4};
    sort(a.begin(), a.end(), bind(&D::cmp, *this, _1, _2));
    for (int x : a) printf("%d ", x);
  }
};

关键问题在于,成员函数 A::cmp 的形参列表看似只有两个 bool cmp(int x, int y),但是因为它是成员函数,需要带着自己绑定的对象调用,它实际上是 bool A::cmp(/*const*/ A&, int x, int y)。那么使用 std::bind,将自己绑定到第一个参数的位置,大概的使用方法见上。这种方法可以使 cmp 有 cv 限定。关于 std::bind 的更多说明见 https://zh.cppreference.com/w/cpp/utility/functional/bind

标签:std,sort,int,pos,vector,报错,__,bool,cmp
From: https://www.cnblogs.com/caijianhong/p/17811781.html

相关文章

  • SortableJS:vuedraggable实现元素拖放排序
    文档:https://sortablejs.github.io/Sortable/github:https://github.com/SortableJS/SortableVue2:https://github.com/SortableJS/Vue.DraggableVue3:https://github.com/SortableJS/vue.draggable.nextnpmhttps://www.npmjs.com/package/vuedraggable#vue2npminst......
  • C++11语法——std::move()
    std::move()在C++中,std::move()用于将对象转换为右值引用。关于左值、左值引用、右值、右值引用左值是一个表示数据的表达式(比如变量名或者解引用的指针),程序可以获取其地址传统的C++引用,即是左值引用。C++11新增右值引用,用&&表示。右值是可出现在赋值表达式的右边,但不......
  • c: struct sort descending and ascending
     /***@filehello.c*@authoryourname(geovindu)*@brief*@idevscodec11,c17windows10*@version0.1*@date2023-11-05**@copyrightCopyright(c)2023**/#include<stdlib.h>#include<stdint.h>#include<stdio.h......
  • 奇数分辨率视频导出报错
    奇数分辨率的导出报错前记:有群u说了个冷知识,说ae里面mp4导出奇数分辨率会报错,我当时就当作个知识点来看待了。最近想起来这件事,就去了解查询了一下,发现是yuv编码还有输出本身的问题。我也只是浅入浅出,内容写的可能有点乱,见谅尝试验证阶段AE内置我用的是23sp版本,记得好像是23版......
  • 下载了powerpaste插件报错
    为什么我下载了powerpaste插件代码中写external_plugins:{powerpaste:"/static/tinymce/powerpaste/plugin.min.js"}然后就会报错tinymce.js:4759GEThttp://localhost:81/static/tinymce/powerpaste/plugin.min.jsnet::ERR_ABORTED404(NotFound)你遇到的问题可能......
  • ./rmblastn: error while loading shared libraries: libzstd.so.1: cannot open shar
     001、问题, ./rmblastn命令报错如下:./rmblastn:errorwhileloadingsharedlibraries:libzstd.so.1:cannotopensharedobjectfile:Nosuchfileordirectory 002、解决方法  003、测试  参考:01、https://www.modb.pro/db/429704 ......
  • springboot启动报错[main] o.a.catalina.core.AprLifecycleListener
    详细信息为:---[main]o.a.catalina.core.AprLifecycleListener:Anincompatibleversion[1.2.17]oftheApacheTomcatNativelibraryisinstalled,whileTomcatrequiresversion[1.2.34]解决方法:下载对应版本的native文件,地址为https://archive.apache......
  • 解决openavsa数据库报错的问题
    报错内容如图解决方法如下:卸载OpenVAS:$sudoapt-getremoveopenvas删除OpenVAS的所有依赖项:$sudoapt-getautoremove删除OpenVAS的所有配置文件:$sudorm-rf/etc/openvas/删除OpenVAS的所有数据:$sudorm-rf/var/lib/openvas/安装OpenVAS:$sudoapt-getinstallopenvas更......
  • xadmin报错处理
    Xadmin运行报错ImportError:cannotimportname'DEFAULT_FORMATS'点进入报错信息的源码注释掉代码#fromimport_export.adminimportDEFAULT_FORMATS,SKIP_ADMIN_LOG,TMP_STORAGE_CLASS新添加代码fromimport_export.formats.base_formatsimportDEFAULT_FORMATSfr......
  • vue3路由转发报错Failed to resolve component: router-link
     //在学习vue3路由转发的时候,总是报路由的一些方法无法识别,undefined报错://App.vue:9[Vuewarn]:Failedtoresolvecomponent:router-link//vue路由跳转报错Cannotreadpropertiesofundefined(reading'push')原因:出在你挂载的位置这个路由的u......