我们可以定义运算符<但人们似乎总是使用类来定义运算符()?
这到底是怎么回事。
我以前在C中学习过这样的泛型,当时我们使用指向函数的指针。
有什么区别?
基本上,您希望您的代码包含最少的惊喜。
假设你的班级T
有一个std::priority_queue<T> pq
。T
是一个存在自然序的类吗?如果是,请为其定义一个operator <
。是否希望根据此排序对pq
进行优先级排序?如果是这样的话,让它使用operator <
就完成了。
然而,通常情况下,T
是一个没有内在排序概念的类。想象一个存储name
、startingDate
和salary
的类Employee
。没有通用的排序——给定两名员工,不清楚哪一个是<
。
同时,你可能想要一个std::priority_queue<Employee>
,这取决于谁的收入最高。至少。或者谁在公司工作时间最长。因此,您将使用特定的比较器进行比较。
在某种程度上,优先级队列比较器和operator <
是独立的概念。如果你有一个自然可排序的类,那么给它operator <
。如果您想要一个优先级队列,请给它一个适当的谓词。如果那个谓词恰好是operator <
,就让它使用它吧。
至于为什么使用带有operator()
的类而不是指向函数的指针,我认为主要原因是键入和构造使用比较器(如std::priority_queue
或std::map
)的类模板将比较器的类型作为其模板参数(它们没有其他选项)。然后,在构造容器时,您有两个选项:提供比较器类型的对象,或者让类在默认构造下创建一个对象。
当比较器的类型是一个类(具有默认构造函数,通常存在于这些函子类中)时,std::priority_queue
的构造函数可以默认构造它并工作。如果您使用函数指针,队列的类型将是例如std::priority_queue<T, SomeContainer, bool (*)(const T&, constT&)>
,并且您必须将适当的函数指针传递给您创建的每个队列。