对于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
为什么要这样做?为什么不能通过键的类型推导比较器功能的类型?
答案 0 :(得分:4)
与函数不同,类模板没有部分推论。如果为类模板提供模板参数,则需要提供所有非默认参数,在set
的情况下,您需要提供比较类型,因为它的默认值为std::less<T>
,即函数指针不能转换为。
有人提议部分扣除,但被拒绝了,目前添加到CTAD的唯一事情是它将通过别名工作。
答案 1 :(得分:2)
您的问题已得到回答,所以这只是解决问题的方法的输入:
您可以为您的类型提供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>
类,该类将默认用于您的类型。
答案 2 :(得分:1)
因为比较器不一定是一个函数(函数指针,偶)。实际上,该参数的默认值为std::less<Key>
,这是带有operator()
的类模板。但是您可以传递可以用两个MyType const&
调用的任何东西的类型并返回bool
,因此需要指定该东西实际上是什么。