我有一个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
中定义一个?
答案 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_queue
和sort
都可以使用cmpFrom
。
答案 2 :(得分:3)
std::sort
函数和std::priority_queue
类模板需要两个不同的东西:sort
需要一个可调用对象,而priority_queue
模板需要一个类型,它允许创建对象。
因此,sort
比priority_queue
更杂乱-您可以将其与函数或函子一起使用。您唯一需要的是为其提供一个真实的对象(当前在代码中,您尝试采用的地址类型是没有意义的。)
要在示例中修复此问题,只需将代码更改为
std::sort(trips, trips + nbRoads, cmpFrom{});