C ++:用于订购元素的结构与函数

时间:2019-04-29 14:14:16

标签: c++ sorting struct priority-queue

我有一个struct,其中有两个字段:

struct road {
    int from, len ;
};

出于某种原因,我需要能够订购road

  • 通过将from升至数组

  • 通过在优先级队列中提升len

因此,我包括了:

#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>

我曾经浏览过一些网站,建议重载operator<,但是由于这两种可能的排序方式感觉不对,并且只能解决这两种方式之一。

通过弄乱教科书,我可以使它起作用:

bool cmpFrom (const road & a, const road & b) {
    return (a.from < b.from) ;
}

struct cmpLen {
    bool operator () (const road & a, const road & b){
        return (a.len < b.len) ;
    }
};

用于:

std::sort(trips, trips + nbRoads, &cmpFrom) ;
std::priority_queue<road, std::vector<road>, cmpLen> pickRoad ;

trips当然是road []的地方。

它可以完美编译(没有尝试运行它,但是应该没问题),但是用两种完全不同的方式定义两个非常相似的比较器似乎很奇怪,因此没有办法定义两种比较方法。用同样的方式?

cmpFrom的定义更改为

struct cmpFrom {
    bool operator () (const road & a, const road & b){
        return (a.from < b.from) ;
    }
};

给予

chantier.cpp: In function ‘int main()’:
chantier.cpp:38:48: error: expected primary-expression before ‘)’ token
     std::sort(trips, trips + nbRoads, &cmpFrom) ;

我认为这意味着“您在给我参考时给了我一个字”。

写作时

bool cmpLen (const road & a, const road & b) {
    return (a.len <= b.len) ;
}

给予

chantier.cpp: In function ‘int main()’:
chantier.cpp:52:56: error: type/value mismatch at argument 3 in template parameter list for ‘template<class _Tp, class _Sequence, class _Compare> class std::priority_queue’
     std::priority_queue<road, std::vector<road>, cmpLen> pickRoad ;
                                                        ^
chantier.cpp:52:56: note:   expected a type, got ‘cmpLen’
chantier.cpp:56:30: error: request for member ‘top’ in ‘pickRoad’, which is of non-class type ‘int’
...

是否有一种方法可以使这些比较方法中的一种适用于两个容器?还是有第三种方法可以同时适用于两者?

如果我需要对两个容器使用相同的顺序怎么办?是否需要定义两次相同的比较方法,但是在struct中定义一个?

3 个答案:

答案 0 :(得分:5)

将两者都定义为结构更容易,因为您总是可以根据类型创建对象,并且其行为将与预期的一样,但是从函数中获取类型并将其用作函数的调用者要困难得多。

实际上您与struct cmpFrom差不多。但是,您已经正确地注意到std::sort需要比较器 object (例如函数),而不是类型。当然,在&cmpFrom是类型的情况下执行cmpFrom是无效的C ++。相反,您需要创建该类型的对象。多亏了定义的operator(),该对象才可以被调用并执行您想要的操作。因此,只需像这样调用std::sort

std::sort(trips, trips + nbRoads, cmpFrom{});

答案 1 :(得分:5)

您几乎拥有它。在std::sort中,您需要一个可以调用operator()的对象。使用

bool cmpFrom (const road & a, const road & b) {
    return (a.from < b.from) ;
}
std::sort(trips, trips + nbRoads, &cmpFrom);

之所以起作用,是因为可以像函数一样使用函数指针。当您将cmpFrom更改为

struct cmpFrom {
    bool operator () (const road & a, const road & b){
        return (a.from < b.from) ;
    }
};

您不能再使用std::sort(trips, trips + nbRoads, &cmpFrom);,因为您不能将&应用于类型名称。相反,您需要做的是获取cmpFrom的对象,然后像这样

std::sort(trips, trips + nbRoads, cmpFrom{});

现在priority_queuesort都可以使用cmpFrom

答案 2 :(得分:3)

std::sort函数和std::priority_queue类模板需要两个不同的东西:sort需要一个可调用对象,而priority_queue模板需要一个类型,它允许创建对象。

因此,sortpriority_queue更杂乱-您可以将其与函数或函子一起使用。您唯一需要的是为其提供一个真实的对象(当前在代码中,您尝试采用的地址类型是没有意义的。)

要在示例中修复此问题,只需将代码更改为

std::sort(trips, trips + nbRoads, cmpFrom{});