4

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

它给出了以下错误:bool (Sorter::)(D&, D&)' does not matchbool 类型的参数 (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

4 回答 4

6

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不应该修改对象。

于 2010-05-11T05:16:57.730 回答
4

除非您有很好的理由不这样做,否则只需定义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

猜测一下,您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());

请注意,这不使用自由函数。对于这种目的,函子通常是优选的。我还使用命名空间来显示正在排序的对象与不同的排序方式之间的关联。您可以改为将它们设为嵌套类,但我通常更喜欢公共命名空间(保持耦合尽可能松散)。

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

于 2010-05-11T06:07:35.223 回答
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));

您将需要 boost 库才能使其工作,并且您将需要#include <boost/bind.hpp>.

于 2010-05-11T05:38:39.707 回答
1

我认为没有任何理由将其sortByNumber作为分类器类的成员函数。如果将其设为自由函数,则可以更轻松地进行排序,避免所有丑陋的绑定代码。此外,您应该const在代码中适用的任何地方使用它。以下是使用自由函数执行此操作的示例:

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

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

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

于 2010-05-11T05:35:03.647 回答