C ++:如何使用其参数之一对从类派生的对象的向量进行排序

时间:2019-04-04 22:17:17

标签: c++ c++11

我正在尝试对从项目中的类创建的对象向量进行排序。

我有两个类-播放列表和ListIndex,它们是从List_base类继承的。在List_base类中,我想按对象名称对对象(播放列表或ListIndex)的向量进行排序。 name属性在List_base类中定义。我尝试使用比较名称字段的结构或函数并将其传递给sort函数。我遇到各种错误。我是C ++的新手,并在此错误中停留了很长时间

具有比较功能的List_base排序方法

//the function should be able to get either Playlist vector
// or ListIndex vector (both inherits from List_base)
void List_base::sortList(vector<List_base> data) {
    sort(data.begin(), data.end(), compFunc());
}

bool List_base::compFunc(List_base *a, List_base *b) {
    return a->getName().compare(b->getName()) > 0;
}

名称字段在List_base类中声明:

class List_base
{
    public:
        List_base(string name);
        string getName();
        void sortList(vector<List_base> data);
        virtual ~List_base();

    protected:

    private:
        string name;
        bool compFunc(List_base *a, List_base *b);
};

我在做什么错?我什至不能专注于特定的错误。 我也尝试过投放,但也失败了

请帮忙!

1 个答案:

答案 0 :(得分:1)

std::sort期望您传递的比较器是某种可调用的类型,无论它是函数指针,函子,lambda等。它只需要可以用诸如bool compare(const T& left, const T& right)这样的签名来调用的东西。 / p>

第一个问题是传递compFunc()调用函数 compFunc。这将失败,因为compFunc需要两个参数。您应该传递函数本身,而不是其返回值:

sort(data.begin(), data.end(), compFunc);

第二个问题是,在您的compare函数中,您应该通过引用引用而不是指针来接受参数:

bool compFunc(const List_base& a, const List_base& b);

其中List_base正是您要排序的元素类型。

第三个问题是compFunc非静态成员函数。这意味着此功能取决于要使用的List_base 实例,并且您需要一个秘密的this参数来调用它,如this->compFunc(...)所示。您应该改为使其成为static或非成员,以便可以将其视为普通函数。

class List_base {
    /* ... */
    static bool compFunc(const List_base& a, const List_base& b);
};

bool List_base::compFunc(const List_base& a, const List_base& b){
    return a.name < b.name;
}

此时您的排序应该可以进行。如果要使用List_base::sortList以外的排序结果,则应通过 reference 接受data,以便调用者可以看到您所做的更改。当前,sortList按值接受列表,这意味着它始终会收到您传递的内容的副本


也许对这一切的最干净的解决方法是“小于”运算符(<),标准库在许多情况下默认情况下会使用该运算符来比较用户定义的类型。这可能类似于以下内容:

class List_base {
    /* ... */
    friend bool operator<(const List_base& a, const List_base& b){
        return a.name < b.name;
    }
};

使用此方法,您无需显式指定自己的比较器,并且排序现在变得简单

sort(data.begin(), data.end());