为了账号安全,请及时绑定邮箱和手机立即绑定

使用成员函数作为比较器进行问题排序

使用成员函数作为比较器进行问题排序

C++
心有法竹 2019-12-15 15:08:03
尝试编译以下代码时,出现此编译错误,该怎么办?ISO C ++禁止使用不合格或带括号的非静态成员函数的地址形成指向成员函数的指针。class MyClass {   int * arr;   // other member variables   MyClass() { arr = new int[someSize]; }   doCompare( const int & i1, const int & i2 ) { // use some member variables }    doSort() { std::sort(arr,arr+someSize, &doCompare); }}; 
查看完整描述

3 回答

?
慕的地8271018

TA贡献1796条经验 获得超4个赞

doCompare必须是static。如果doCompare需要来自MyClass您的数据,可以MyClass通过更改以下内容将其用作比较函子:


doCompare( const int & i1, const int & i2 ) { // use some member variables } 

进入


bool operator () ( const int & i1, const int & i2 ) { // use some member variables } 

并致电:


doSort() { std::sort(arr,arr+someSize, *this); }

另外,不doSort缺少返回值吗?


我认为应该可以使用std::mem_fun某种绑定将成员函数转换为自由函数,但是目前确切的语法让我回避了。


编辑: Doh,std::sort按值取函子可能是个问题。为了解决这个问题,将函子包装到类中:


class MyClass {

    struct Less {

        Less(const MyClass& c) : myClass(c) {}

        bool operator () ( const int & i1, const int & i2 ) {// use 'myClass'} 

        MyClass& myClass;

    };

    doSort() { std::sort(arr,arr+someSize, Less(*this)); }

}



查看完整回答
反对 回复 2019-12-16
?
qq_花开花谢_0

TA贡献1835条经验 获得超6个赞

正如Andreas Brinck所说,doCompare必须为静态(+1)。如果您必须在比较器函数中使用状态(使用该类的其他成员),则最好使用函子而不是函数(这样会更快):


class MyClass{


   // ...

   struct doCompare

   { 

       doCompare( const MyClass& info ) : m_info(info) { } // only if you really need the object state

       const MyClass& m_info;


       bool operator()( const int & i1, const int & i2  )

       { 

            // comparison code using m_info

       }

   };


    doSort() 

    { std::sort( arr, arr+someSize, doCompare(*this) ); }

};

使用函子总是更好,键入的时间更长(这可能不方便,但是很好...)


我认为您也可以将std :: bind与成员函数一起使用,但是我不确定如何并且那也不容易阅读。


今天,我们可以使用c ++ 11编译器,因此您可以改用lambda,代码虽然较短,但语义完全相同。



查看完整回答
反对 回复 2019-12-16
?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

v

Rob提出的解决方案现在是有效的C ++ 11(无需Boost):


void doSort()

{

  using namespace std::placeholders;

  std::sort(arr, arr+someSize, std::bind(&MyClass::doCompare, this, _1, _2));

}

确实,正如Klaim所提到的,lambda是一个选项,有点冗长(您必须“重复”这些参数是整数):


void doSort()

{

  std::sort(arr, arr+someSize, [this](int l, int r) {return doCompare(l, r); });

}

C ++ 14 auto在这里支持:


void doSort()

{

  std::sort(arr, arr+someSize, [this](auto l, auto r) {return doCompare(l, r); });

}

但是,您仍然声明参数是通过副本传递的。


那么问题是“哪一个是最有效的”。特拉维斯·高克尔(Travis Gockel)处理了该问题:Lambda vs Bind。他的基准测试程序在我的计算机上提供(OS X i7)


                        Clang 3.5    GCC 4.9

   lambda                    1001        7000

   bind                3716166405  2530142000

   bound lambda        2438421993  1700834000

   boost bind          2925777511  2529615000

   boost bound lambda  2420710412  1683458000

其中lambda的lambda直接使用,lambda bound是存储在中的lambda std::function。


因此看来,lambda是更好的选择,这并不奇怪,因为为编译器提供了可从中获利的更高级别的信息



查看完整回答
反对 回复 2019-12-16
  • 3 回答
  • 0 关注
  • 365 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信