使用我的define函数错误进行c ++ STL排序

时间:2016-01-18 03:45:56

标签: c++ stl

我知道我可以使用我的define函数对数组进行排序,就像这样:

bool cmp(int a, int b){
    return a > b;
}

class SortTest{
public :
    void testSort(){
        int a[] = { 1, 3, 4, 7, 0 };
        int n = 5;
        sort(a, a + n, cmp);                //work
        for (int i = 0; i < n; i++){
            cout << a[i] << " ";
        }
    }
};

但是如果我在SortTest类中使用函数cmp,它就不起作用了。

class SortTest{
public :
    bool cmp(int a, int b){
        return a > b;
    }
    void testSort(){
        int a[] = { 1, 3, 4, 7, 0 };
        int n = 5;
        sort(a, a + n, &SortTest::cmp);             // not work
        for (int i = 0; i < n; i++){
            cout << a[i] << " ";
        }
    }
};

我定义了两个模板SortClass和SortClass2,如greater template,SortClass2使用operator(),SortClass是cmp,只使用operator()工作。

template <class T> struct SortClass {
    bool cmp (const T& x, const T& y) const { return x > y; }
};

template <class T> struct SortClass2 {
    bool operator()(const T& x, const T& y) const { return x > y; }
};

class SortTest{
public :
    bool operator() (const int& x, const int& y) const { return x > y; }
    void testSort(){
        int a[] = { 1, 3, 4, 7, 0 };
        int n = 5;
        //sort(a, a + n, &SortClass<int>::cmp); //not work
        //sort(a, a + n, SortClass2<int>());    //work
        sort(a, a + n, SortTest());             //work
        for (int i = 0; i < n; i++){
            cout << a[i] << " ";
        }
    }
};

所以,我的问题是为什么SortTest类中的cmp函数不起作用,但使用operator()是否有效?如果cmp函数不在类中,它工作正常。非常感谢。

3 个答案:

答案 0 :(得分:5)

问题是&SortClass<int>::cmp正在向SortClass的成员函数传递指针,但是sort没有任何实例可以调用成员函数。 / p>

尝试添加以下代码段:

int i = 5, j = 10;
(&SortClass<int>::cmp)(i, j) // won't work

SortClass<int> test;
test.cmp(i,j) // will work because it is being called on an instance.

如果您将其更改为静态函数,则可以使其正常工作:

bool cmp (const T& x, const T& y) const { return x > y; }

为:

static bool cmp (const T& x, const T& y) { return x > y; }

请注意,必须删除函数参数和函数体之间的const,因为静态函数不会对此指针起作用。

另一方面,为什么所有这些课程呢? C ++的优势之一是你可以混合编程范例,而你不必像Java一样拥有类中的所有东西。为什么不将它们作为自由函数?

答案 1 :(得分:4)

您的问题有几种解决方案,但都有不同的注意事项:

  1. 使比较功能静止。

     static bool cmp(int a, int b) ...
    

    当您只想从全局命名空间中删除cmp符号时,这应该是最佳解决方案,并且它适用于任何编译器和c ++版本。

  2. 使用lambda函数调用cmp

    sort(a, a + n, [this](int a, int b) { return cmp(a,b); });
    

    这用lambda函数包围了对cmp的调用。仅适用于c ++ 11及更高版本。

  3. 使用lambda函数完成工作

     sort(a, a + n, [](int a, int b) { return a > b; });
    

    这完全消除了对cmp的需求。如果你只需要在这个地方进行比较,我会推荐这种方法

  4. 使用boost :: bind

     sort(a, a + n, boost::bind(&SortTest::cmp, this));
    

    但这种方法需要boost libraries()

  5. 使用std :: bind

     sort(a, a + n, std::bind(&SortTest::cmp, _1, this));
    
  6. 仅为完整性:使用仿函数对象

     class cmp { 
         public: 
         bool operator()(int a, int b) { return a > b; }
     }; 
    

答案 2 :(得分:1)

因为std::sort假设传递给它的比较函数对象可以通过类似comp(lht, rhs);的语法调用,而成员函数指针则不能。调用它需要一个对象。

您可以使用std::mem_fnstd::bind作为单词解释。