传递一个类方法而不是std :: sort中的函数

时间:2010-05-11 05:10:45

标签: c++ sorting stdvector

在一个类中,我试图通过传递同一个类的方法对向量进行排序。但它在编译时会出错。谁能说出问题是什么?谢谢!

它给出以下错误:     bool (Sorter::)(D&, D&)' does not match类型的参数bool(Sorter :: *)(D&,D&)'

我也尝试过使用sortBynumber(D const& d1, D const& d2)

#include<vector>
#include<stdio.h>
#include<iostream>
#include<algorithm>

class D {
      public:                   
             int getNumber();            
             D(int val);
             ~D(){};
      private:
              int num;
};

D::D(int val){
         num = val;
         };

int D::getNumber(){
    return num;
};


class Sorter {
      public:                   
             void doSorting();  
             bool sortByNumber(D& d1, D& d2);
             std::vector<D> vec_D;          
             Sorter();
             ~Sorter(){};
      private:
              int num;
};

Sorter::Sorter(){                 
        int i;
        for ( i = 0; i < 10; i++){
            vec_D.push_back(D(i));
           }
         };

bool Sorter::sortByNumber(D& d1, D& d2){
     return d1.getNumber() < d2.getNumber();
     };

void Sorter::doSorting(){
     std::sort(vec_D.begin(), vec_D.end(), this->sortByNumber);
     };




int main(){    
    Sorter s;
    s.doSorting();

    std::cout << "\nPress RETURN to continue...";
    std::cin.get();

    return 0;
}

4 个答案:

答案 0 :(得分:5)

Sorter::sortByNumber成为静态。由于它不引用任何对象成员,因此您无需更改任何其他内容。

class Sorter {
public:                   
    static bool sortByNumber(const D& d1, const D& d2);
    ...
};

// Note out-of-class definition does not repeat static
bool Sorter::sortByNumber(const D& d1, const D& d2)
{
    ...
}

您还应该使用const引用,因为sortByNumber不应该修改对象。

答案 1 :(得分:3)

除非你有充分的理由不这样做,否则只需为你要排序的项目类型定义operator<,并完成它:

class D { 
    int val;
public:
    D(int init) : val(init) {}
    bool operator<(D const &other) { return val < other.val; }
};

class sorter { 
    std::vector<D> vec_D;
public:
    void doSorting() { std::sort(vec_d.begin(), vec_D.end()); }
};

你编写sorter课程的方式取决于知道关于D课程内部的批次,以至于他们实际上是一个单一的class(例如,看起来没有其他任何东西都不能做任何事情)。

猜测一下,您的sorter可能是您真实代码的精简版。 SortByNumber听起来像原始代码可能支持许多不同类型的键,如:

class D { 
    std::string name;
    int height;
    int weight;
// ...
};

并且您希望能够按名称,身高或体重对D个对象进行排序。在这样的情况下,比较实际上仍然与D类相关,所以我可能会将它们放入一个共同的命名空间:

namespace D { 
class D { 
    std::string name;
    int height;
    int weight;
public:
    friend class byWeight;
    friend class byHeight;
    friend class byName;
    // ...
};

struct byWeight { 
   bool operator()(D const &a, D const &b) { 
       return a.weight < b.weight;
   }
};

struct byHeight {
    bool operator()(D const &a, D const &b) { 
        return a.height < b.height;
    }
};

struct byName { 
    bool operator()(D const &a, D const &b) { 
        return a.name < b.name;
    }
};
}

然后排序看起来像:

std::vector<D::D> vec_D;

// sort by height:
std::sort(vec_D.begin(), vec_D.end(), D::byHeight());

// sort by weight:
std::sort(vec_D.begin(), vec_D.end(), D::byWeight());

// sort by name:
std::sort(vec_D.begin(), vec_D.end(), D::byName());

请注意,使用免费功能。出于这种目的,通常优选仿函数。我还使用了一个名称空间来显示正在排序的对象和排序它的不同方法之间的关联。您可以使它们成为嵌套类,但我通常更喜欢使用公共命名空间(保持耦合尽可能松散)。

在任何情况下,如果可以避免,我会通过对象的公共接口访问原始数据(甚至是只读访问)(在这种情况下,它可以)

答案 2 :(得分:2)

我认为sortByNumber()没有理由成为会员功能。当它是一个成员函数时,它可以访问它不需要的东西(因此不应该访问)。提取方法并将其重构为函数对象:

struct sortByNumber {
    bool operator()(const D& d1, const D& d2) const {
        return d1.getNumber() < d2.getNumber();
    }
};

或使其成为免费功能。给定选择你应该更喜欢一个函数对象,因为这使编译器可以内联代码,如果它选择的话。然后,您可以这样排序:

std::sort(vec_D.begin(), vec_D.end(), sortByNumber());

也就是说,你可以使用boost::bind()

来编译代码
std::sort(vec_D.begin(), vec_D.end(),
          boost::bind(&Sorter::sortByNumber, this, _1, _2));

您需要使用增强库才能工作,您需要#include <boost/bind.hpp>

答案 3 :(得分:1)

我认为没有理由将sortByNumber作为类Sorter的成员函数。如果你使它成为一个自由函数,你可以更容易地进行排序,避免所有丑陋的绑定代码。此外,您应该在代码中的任何位置使用const。以下是使用自由函数执行此操作的示例:

首先将int getNumber()更改为const函数int getNumber() const;

然后再次编写你的自由函数sortByNumber,通过const引用获取参数。  bool sortByNumber(const D& d1, const D& d2);

您可以将sort称为: std::sort(vec_D.begin(), vec_D.end(), sortByNumber);