在通用编程中选择类型参数

San*_*ket 2 c++ stl typename

我在cpp ref中遇到过这段代码

template<
    class T,
    class Container = std::vector<T>,
    class Compare = std::less<typename Container::value_type>
> class priority_queue;
Run Code Online (Sandbox Code Playgroud)

typename Container::value_type在上述声明中使用的目的究竟是什么?以下不起作用吗?

template<
    class T,
    class Container = std::vector<T>,
    class Compare = std::less<T>
> class priority_queue;
Run Code Online (Sandbox Code Playgroud)

for*_*818 7

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

对于这个例子的目的,可以说你有一个strange_containervalue_typestd::pair<T,T>你要实例与模板

priority_queue<T,strange_container<T>>
Run Code Online (Sandbox Code Playgroud)

然后你的默认值Compare = std::less<T>不适用于该容器,同时Compare = std::less<typename Container::value_type>会正确比较对.

请注意,上面的内容不适用于C++ 17,因为(来自cppref):

如果T与Container :: value_type的类型不同,则行为未定义.(自C++ 17起)

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