C++:结构与用于排序元素的函数

C++ : struct vs function for ordering elements

本文关键字:元素 函数 排序 用于 结构 C++      更新时间:2023-10-16

我有一个包含两个字段的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内有一个?

你几乎拥有它。 在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.

将两者定义为结构更容易,因为您始终可以从类型创建对象,并且它将按预期运行,但是从函数获取类型并让它充当函数的调用者要困难得多。

事实上,你几乎和struct cmpFrom在一起.但是,您已经正确注意到std::sort需要比较器对象(例如函数),而不是类型。当然,在cmpFrom类型&cmpFrom是无效的C++。相反,您需要创建该类型的对象;由于定义了operator(),该对象将是可调用的,并且可以执行您想要的操作。所以就这样称呼std::sort

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

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

正因为如此,sortpriority_queue更杂食 - 您可以将其与函数或函子一起使用。您唯一需要的是为其提供一个真实的对象(而当前在您的代码中,您正在尝试获取一种类型的地址,这毫无意义)。

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

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