当我们为std::sort
提供比较器功能时,我们使用以下重载:
template< class RandomIt, class Compare >
void sort( RandomIt first, RandomIt last, Compare comp );
其中std::sort
的比较器函数应具有以下语法:
bool cmp(const Type1 &a, const Type2 &b);
但是您可以看到a
和b
可能具有不同的类型。 cppreference说:
类型
Type1
和Type2
必须使得类型RandomIt
的对象 可以取消引用,然后隐式转换为两者。
但是当我尝试对单个数组进行排序时,我仍然无法完全理解如何在一个数组中拥有两种不同类型。
有人可以为std::sort
的比较器功能提供一个不同类型的小例子吗?
答案 0 :(得分:20)
这与数组中存储的内容无关,只能存储一种类型。关于比较器功能是什么。例如:
struct Animal {};
struct Cat : Animal {};
struct Dog : Animal {};
struct Hound : Dog {};
bool cmp(const Animal &a, const Animal &b);
即使您有Dog
,Cat
或Hound
的列表,您仍然可以使用函数cmp
对它们进行排序,因为它们都是隐式可转换的。即。
std::vector<Hound> hounds;
... // fill hounds
std::sort(hounds.begin(), hounds.end(), cmp);
您甚至可以想象Type1
和Type2
不相同的情况,例如:
bool cmp(const Animal &a, const Dog &b);
etc ...
尽管这种情况非常罕见。
类型1 (动物)和类型2 (狗)的类型必须使得RandomIt (猎犬)类型的对象可以被取消引用然后隐式转换为两者。 。
要点是,对cmp
函数可以采用的类型的限制不包括一般性。在某些情况下,这是一个好主意,但在这种情况下,它会过分严格,可能会给边缘案例实现带来问题。此外,cmp
中使用的std::sort
函数受Compare提出的要求的约束(可能是为了简化)。 比较要求用于其他各种事物,例如std::max
。
答案 1 :(得分:13)
但是我仍然无法确切地知道尝试对它进行排序时如何在一个数组中拥有2种不同类型。
数组中不能有两种不同的类型。比较器并不建议有可能。之所以这样指定,仅仅是因为:
因此,该规范提供的合同比“显而易见”的合同更宽松,以帮助我们的代码在需要时更加灵活。作为一个玩具示例,假设我们有这个比较器:
auto cmp(int a, long b) -> bool { return a < b; }
为什么阻止我们使用此完全合法的(尽管很愚蠢的)函数对整数数组进行排序?
答案 2 :(得分:7)
但是我仍然无法确切地知道尝试对它进行排序时如何在一个数组中拥有2种不同类型。
你不能。
但是 Compare 的要求不仅是对数组进行排序,还是对所有数组进行排序!
在任何时候您都想将一件事与另一件事进行比较。
webpack.mix.js
小于minutes(42)
吗?是!在这种情况下,您可能会发现比较器很有用。
比较是一个更通用的概念,可以在整个语言中找到用途。
有人可能会为std :: sort的比较器函数提供一个具有不同类型的小示例
其他人显示了一些示例,这些示例指示您必须多么愚蠢地找到针对“ hours(1)
”使用的“有用”示例。
但这不是“ std :: sort的比较器函数”。这是 a 比较器函数,您恰好与std::sort
一起使用。
的确,这样做时,您可能希望选择特定的比较器来接受相同类型的操作数。
答案 3 :(得分:4)
但是我仍然无法确切知道如何在单个数组中拥有2种不同类型
在一个数组中不能有两种不同的类型。
一个数组只能有单一类型的对象。但是,该单一类型必须可以隐式转换为cmp
的两种参数类型。
有人可能会为std :: sort的比较器功能提供一个具有不同类型的小示例吗?
您在这里:
int arr[] = {1, 2, 3, 0};
auto cmp = [](const int &a, const long &b) {
return a < b;
};
std::sort(std::begin(arr), std::end(arr), cmp);
请注意cmp
的两个不同参数。这只是一个最小的例子,从技术上讲是正确的,但公认是荒谬的。坦白说,我从未遇到过这样的情况:对于比较函数的参数使用不同的类型会很有用。
答案 4 :(得分:4)
比较器的要求比您想象的要宽松得多:
bool
。因此,有效但相当无用的比较器将是:
template <class... X>
auto useless(X&&...) { return nullptr; }
答案 5 :(得分:1)
Compare
上的类型要求不是要对要排序的序列元素说太多,而是允许所有comp
if (comp(*first, *other))
有效。
大部分时间,Type1
等于Type2
,但不要求它们相等。