【问题标题】:Omitting type parameter for greater template in C++ STL在 C++ STL 中省略更大模板的类型参数
【发布时间】:2018-06-04 18:50:12
【问题描述】:

这是我在书中读到的一行代码

priority_queue<IteratorCurrentAndEnd, vector<IteratorCurrentAndEnd>, greater<>> min_heap;

其中IteratorCurrentAndEnd 是一个实现operator&gt; 方法的类。为什么我们可以有greater&lt;&gt; 而不是greater&lt;IteratorCurrentAndEnd&gt;?我检查并阅读了类似的内容,

template< class T = void >
struct greater;

但我真的不知道这意味着什么。它与void 类型有关吗?它到底是什么?

谢谢。

【问题讨论】:

标签: c++ c++11 stl generic-programming function-object


【解决方案1】:

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

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

正如reference 中所述,std::greater&lt;void&gt; 现在是一个函子,其中包含一个类似于

operator() 函数模板
template< class T, class U>
constexpr auto operator()( T&& lhs, U&& rhs ) const
{
    return std::forward<T>(lhs) > std::forward<U>(rhs);
}

这实现了两种类型之间的一般比较(和现在想出的完全一样)。

【讨论】:

    【解决方案2】:

    是的,它与 sn-p 中的void 相关,但 void 作为类型本身并没有什么特别之处。该语法表示struct greater 采用一个模板参数(即一种类型),但它可以省略,如果省略,void 将用作该类型。它类似于常规函数的默认值语法:

    void foo(int x = 7);
    
    foo(5); // x = 5
    foo(); // x = 7
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-04
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多