为什么要在 C++ 标准容器中为模板参数起别名?

Why alias a template parameter in C++ standard containers?

查看Microsoft的STL代码(具体std::vector),我遇到了以下代码行(无关代码替换为/* ... */):

// CLASS TEMPLATE vector
template <class _Ty, class _Alloc = allocator<_Ty>>
class vector // varying size array of values
{ 
    /* ... */
public:

   /* ... */
   using value_type = _Ty;
   using allocator_type = _Alloc;
   using pointer = typename _Alty_traits::pointer;
   using const_pointer = typename _Alty_traits::const_pointer;
   using reference = _Ty&;
   using const_reference = const _Ty&;
   using size_type = typename _Alty_traits::size_type;
   using difference_type = typename _Alty_traits::difference_type;
   /* ... */
};

我想知道为什么这里使用为模板类型分配类型别名的约定?

该约定实际上用于提供“特征”。这些类型的命名遵循一些约定,允许根据这些特征编写 distance 等函数,并使其适用于许多容器。

而且我很确定标准 C++ 库的这些类型是规范的一部分,他们必须遵守它。

I was wondering why the convention of assigning a type alias to a template type is used here?

因为是

  • 标准的做法,
  • 使代码不易出错,
  • 减少打字,
  • 更具可读性,并且
  • 以上所有让生活变得轻松!

例如,让我们考虑 const_pointer, public template alias of std::vector

using const_pointer   = typename _Alty_traits::const_pointer;

在某些时候,您想知道这种类型并在函数中使用,没有上述别名怎么可能?

当然,你can write

#include <memory> // std::allocator_traits

using const_pointer = typename std::allocator_traits<typename std::vector</*type*/>::allocator_type>::const_pointer;

程序中的任何位置。但这往往 更容易出错 的情况(例如丢失一些 typename 等等),并且 更多的输入 .

因此,收集这些类型的容器并提供 public-aliases-types 是有意义的。

I was wondering why the convention of assigning a type alias to a template type is used here?

假设您有一个接受 STL 容器的模板函数(std::vectorstd::dequestd::setstd::multi_set、...)

template <typename T>
void foo (T const & t)
 {
   // ...
 }

并且您需要包含值的类型。

您可以在 foo() 中简单地写

 using needed_type = typename T::value_type;

这适用于 std::vectorstd::dequestd::setstd::multi_setstd::arraystd::mapstd::multi_map

C++ 标准要求 std::vector 提供大量嵌套名称,而这些正是问题要问的。这就是 value_typeallocator_typepointer 等存在的原因。当您需要它们引用的类型时,您可以在代码中使用这些名称。例如,在用户代码中 std::vector<int>::iterator 引用 std::vector<int> 提供的迭代器类型并不罕见。

至于为什么它们是这样写的,这是一个更广泛的一致性问题。 C++ 标准库(Microsoft 提供的)的整个 Dinkumware 实现中的模板使用 _Ty 作为一般类型的基本名称。如果有两种类型,您会看到 _Ty1_Ty2。当名称有内部类型定义时,它将是 _Myty(对于“我的”类型)。这种一致性使维护代码变得更加容易。