【问题标题】:How can I sort an array using a custom comparator?如何使用自定义比较器对数组进行排序?
【发布时间】:2013-12-07 23:25:58
【问题描述】:

当我从下面的代码中调用 build 函数时,我收到以下编译错误:

error C3867: 'SuffixArray::cmp': function call missing argument list; use '&SuffixArray::cmp' to create a pointer to member
error C2780: 'void std::sort(_RanIt,_RanIt)' : expects 2 arguments - 3 provided

这是我的代码:

class A{
private:
    std::string text;
    std::vector<int> array;

    bool cmp(int a, int b) {
        return std::lexicographical_compare(text.begin() + a, text.end(),
                                            text.begin() + b, text.end());
    }

    void build(const std::string &str, std::vector<int> &vec) {

        // Some vector values actions.

        std::sort(vec.begin(), vec.end(), cmp);
    }
};

这里有什么问题?我正在使用 Visual C++ 编译器。

【问题讨论】:

    标签: c++ sorting vector stl comparator


    【解决方案1】:

    您的比较函数A::cmpA 的非静态成员。因此,它需要三个参数:除了显式声明的两个参数外,它还需要一个指向A 的指针,以成为隐式可用的this。它还具有与普通函数指针不同的类型:bool (A::)(int, int),当按值传递时会衰减为bool (A::*)(int, int)

    你可以std::bind()你的函数到一个合适的对象,但是:

    std::sort(vec.begin(), vec.end(),
              std::bind(&A::cmp, this, std::placeholders::_1, std::placeholders::_2));
    

    【讨论】:

    • 我本来打算建议他把它变成一个静态函数……你的建议更完整。
    • @Jekyll:建议static 成员也是我的第一个想法,但代码实际上在A::cmp() 函数中使用了A::text,即实际上需要该对象。也就是说,将函数设为static 并不能解决问题!
    • 既然c++11才引入了bind函数,不知道在新标准之前怎么处理呢?(其实不需要,只是好奇)
    • @SAD:好吧,你可以使用Boostbind()或者编写一个自定义函数对象类,例如:struct cmp { std::string const* name; cmp(std::string const* name): name(name) {} bool operator()(int a, int a) const { return std::lexicographical_compare(...); } };
    【解决方案2】:

    @DietmarKühl 的回答完美地解释了为什么您的代码无法编译。 但是由于C++11,您也可以使用lambda expression,而不是定义比较函数或使其成为静态:

    #include <vector>
    #include <algorithm>
    
    class A{
    private:
        std::string text;
        std::vector<int> array;
    
        void build(const std::string &str, std::vector<int> &vec) {
    
            // Some vector values actions.
    
            std::sort(vec.begin(), vec.end(), [this](int a, int b) {
                return std::lexicographical_compare(text.begin() + a, text.end(),
                                                    text.begin() + b, text.end());
            });
        }
    };
    

    为了能够访问 lambda 表达式中的类成员 text,我捕获了 this 指针。 但是,如果您想要捕获this 的替代方法,请查看this answer

    【讨论】:

      猜你喜欢
      • 2011-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-25
      • 1970-01-01
      • 2023-04-06
      相关资源
      最近更新 更多