在泛型编程中选择类型参数

Choosing the type parameters in generic programming

我在 cpp ref

中看到了这段代码
template<
    class T,
    class Container = std::vector<T>,
    class Compare = std::less<typename Container::value_type>
> class priority_queue;

在上面的声明中使用typename Container::value_type的目的到底是什么?下面的方法不行吗?

template<
    class T,
    class Container = std::vector<T>,
    class Compare = std::less<T>
> class priority_queue;

这更通用:Container 是一个参数,它可能是一个容器(在 T 上参数化),其 value_type 不同于 T。从我的头顶我不知道一个很好的例子,但天真地也没有理由对使用的 Container 施加约束(即 value_type 在你的版本中必须是 T ) .

为了示例,假设您有一个 strange_container,其 value_typestd::pair<T,T>,并且您希望使用

实例化模板
priority_queue<T,strange_container<T>>

那么您的默认 Compare = std::less<T> 将无法与该容器一起使用,而 Compare = std::less<typename Container::value_type> 将正确地比较对。

请注意,自 C++17 起,上述内容不再适用,因为(来自 cppref):

The behavior is undefined if T is not the same type as Container::value_type. (since C++17)

所以看起来在选择签名时考虑到了最大的通用性,直到后来才意识到这种自由度并不是最好的选择。实际上有充分的理由要求 value_typeT 相同,请参见例如 了解更多信息。