c++ - 在泛型编程中选择类型参数

标签 c++ stl typename

我在 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相同,参见例如 here有关更多信息。

关于c++ - 在泛型编程中选择类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49454415/

相关文章:

c++ - 我正在尝试为我的 DynamicArray 类创建一个迭代器。为什么 STL 排序不能与我的迭代器一起使用?

c++ - SGI STL 中的绑定(bind)好友模板

c++ - 列表的 pop_front 不删除列表的元素

c++ - 类型名、类型成员和非类型成员 : is it valid code?

c++ - 为什么一个类不能在没有前向声明的情况下拥有指向另一个类实例的指针?

c++ - 重载 << 错误

c++ - 通过 C a #define(或其他代码/编译时解决方案)省略核心转储?

c# - 使用 COM 互操作将 BSTR 从 C++ 编码到 C#

c++ - Cryptic template 模板参数错误

c++ - 使用自定义链接标志构建 poco 库