C++ 定义实用比较函数(Custom Compare Function) 注意点

学过C++的应该都知道在调用sort算法的时候可以自定义比较函数(map, heap也都有类似的比较函数谓词的定义), 从而实现不同的排序比如可以从小到大或者从大到小,比如如下就是sort函数的申明(摘自cplusplus):

template <class RandomAccessIterator, class Compare>
  void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

其中 comp是一个谓词可以是`函数指针`或者`函数对象`:
comp
Binary function that accepts two elements in the range as arguments, and returns a value convertible to bool. The value returned indicates whether the element passed as first argument is considered to go before the second in the specific strict weak ordering it defines.
The function shall not modify any of its arguments.
This can either be a function pointer or a function object.

那么今天其实我要说的一个注意的问题就是我自己在些程序的时候遇到的,现在分享出来:自定义的比较函数不能是类的成员函数。 其实这个也不难理解, 因为成员函数作为类的成员, 你要在某个具体的类的实例中才能找到对应的代码段或者在内存中的位置, 这样才能被sort 使用用来比较, 这里可能概念上说的也不完全正确, 大概是这么理解一下,先面是我自己写的一个小的测试程序, 一看就应该明白我想讲的意思:

class comp {
    public:
        bool operator() (const int &l, const int &r) const {
            return l > r;
        }
};

bool comp_fun(const int &a, const int &b) {
    return a > b;
}

class Test {
    public:
        bool comp_in_class(const int &a, const int &b) {
            return a > b;
        }

        void test(vector<int> &data) {
            //sort(data.begin(), data.end(), comp_in_class); //<strong>compile error!</strong>
            sort(data.begin(), data.end(), comp_fun);
        }
};

int main(void) {
    vector<int> data;
    data.push_back(1);
    data.push_back(-1);
    data.push_back(12);
    data.push_back(15);
    data.push_back(-8);
    sort(data.begin(), data.end());
    cout<<"defualt compare: ";
    for(vector<int>::size_type i = 0; i != data.size(); ++i)
        cout<<data[i]<<' ';
    cout<<endl; 

    Test t;
    t.test(data);
    cout<<"class method call: ";
    for(vector<int>::size_type i = 0; i != data.size(); ++i)
        cout<<data[i]<<' ';
    cout<<endl; 


    sort(data.begin(), data.end(), comp());
    cout<<"function object: ";
    for(vector<int>::size_type i = 0; i != data.size(); ++i)
        cout<<data[i]<<' ';
    cout<<endl; 

    sort(data.begin(), data.end(), comp_fun);
    cout<<"just function (pointer): ";
    for(vector<int>::size_type i = 0; i != data.size(); ++i)
        cout<<data[i]<<' ';
    cout<<endl; 

    return 0;
}
Written on May 5, 2013