在 C++ STL 中省略更大模板的类型参数

Sea*_*ean 2 c++ stl generic-programming function-object c++11

这是我在一本书上看到的一行代码

priority_queue<IteratorCurrentAndEnd, vector<IteratorCurrentAndEnd>, greater<>> min_heap;
Run Code Online (Sandbox Code Playgroud)

其中IteratorCurrentAndEnd是实现方法的类operator>。为什么我们可以用greater<>来代替greater<IteratorCurrentAndEnd>?我检查并读到了这样的东西,

template< class T = void >
struct greater;
Run Code Online (Sandbox Code Playgroud)

但我实在不知道这意味着什么。和类型有关系吗void?它到底是什么?

谢谢。

dav*_*igh 7

在 C++14 之前,std::greater<T>类模板是基于一个显式类型参数的T。它只允许比较两个相等的类型。否则,在比较不同类型时,必须依赖转换,这可能会在模板参数推导过程中失败。

C++14 已修复此问题,因为现在还存在两种不同类型的一般比较。不是使用新的类模板std::greater<T,U>(可能不会向后兼容,而且肯定也更复杂),而是std::greater<void>使用 C++14 之前不存在的专门化。选择该类型void正是出于这个原因:因为它在 C++14 之前从未使用过——比较voids 没有意义——自动获得向后兼容性,甚至避免引入新的类模板。

正如参考文献中所述,std::greater<void>now 是一个函子,包含operator()类似于以下内容的函数模板

template< class T, class U>
constexpr auto operator()( T&& lhs, U&& rhs ) const
{
    return std::forward<T>(lhs) > std::forward<U>(rhs);
}
Run Code Online (Sandbox Code Playgroud)

这实现了两种类型之间的一般比较(并且与当今的情况完全相同)。