为什么比较函数类型需要指定为模板参数?

Why does comparison function type need to specified as template parameter?

本文关键字:参数 函数 比较 类型 为什么      更新时间:2023-10-16

对于C++中的关联容器,如set,map等,我们需要提供自定义键比较器类型作为模板参数,如下所示。

bool compareMyType(const MyType& a, const MyType& b);
set<MyType, decltype(compareMyType)*> my_set(compareMyType); // OK
set<MyType> my_set(compareMyType); // ERROR

为什么需要这样做?为什么不能通过键的类型来推断比较器函数的类型?

与函数不同,类模板没有部分扣除。 如果为类模板提供模板参数,则需要提供所有非默认参数,set情况下,您需要提供比较类型,因为它默认为std::less<T>,函数指针不可转换为该类型。

有一个获得部分扣除的提议,但它被拒绝了,目前唯一添加到 CTAD 的事情是它将通过别名工作。

您的问题已得到解答,因此这只是您如何解决问题的输入:

您可以为您的类型提供operator<,以避免每次在set中使用它时都必须为其提供较少的函子。

#include <iostream>
#include <set>
struct MyType {
int value;
};
// added operator<
bool operator<(const MyType& l, const MyType& r) {
return l.value < r.value;
}
int main() {
std::set<MyType> my_set = {{3}, {2}, {1}};
for(const MyType& m : my_set) 
std::cout << ' ' << m.value;
std::cout << "n";
}

输出:

1 2 3

如果要将其与基于哈希的容器(如unordered_set(一起使用,您可以类似地添加一个std::hash<MyType>类,该类将默认用于您的类型。

因为比较器不一定是函数(函数指针,偶数(。实际上,该参数的默认值是std::less<Key>,这是一个带有operator()的类模板。但是你可以传递可以用两个MyType const&调用的任何事物的类型并返回一个bool,因此需要指定该事物实际上是什么