C ++中有“typedef”的含义吗?

Is there any spcecial meaning of “typedef” in C++?

当我阅读stdc++代码时,我对下面的行感到困惑。这是一段来自stl_list.h的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template <class _Tp, class _Alloc>                                      
class _List_base                                                        
  : public _List_alloc_base<_Tp, _Alloc,                                
                            _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
{                                                                      
public:                                                                
  typedef _List_alloc_base<_Tp, _Alloc,                                
                           _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
          _Base;  /* Is _Base a kind of type?*/                              
  typedef typename _Base::allocator_type allocator_type;                

  _List_base(const allocator_type& __a) : _Base(__a) {/* How can a type be initiated like this?*/                  
    _M_node = _M_get_node();                                            
    _M_node->_M_next = _M_node;                                        
    _M_node->_M_prev = _M_node;                                        
  }
}

令我困惑的是_Base。这个名字是由typedef定义的。我认为这是一种类型。但初始化列表中出现了_Base。我如何理解这种用法?或者你帮我贴一些有用的链接。


typedef为一个类型声明了一个别名—如果您愿意,可以使用速记。

它的语法与声明变量的语法完全相同,但它不会为指定类型创建别名:

1
2
int a;         // a is a variable of type int
typedef int B; // B is an alias for type int

(注意,他们经常说typedef original-type alias,但这是一个不正确的规则——例如,如果函数指针失败了——而且这是一个不需要理由就可以记住的规则)

对于静态成员,类型别名的作用域是——在没有其他限定符的情况下可以在类内部访问,而从外部需要限定符(_List_base::_Base)。

对于您的具体案例来说,它只是一个简单的引用基类,即_List_alloc_base<_Tp, _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless>,每次完全编写都是非常麻烦的。

它出现在初始化列表中,因为构造函数正在调用基类的构造函数(即_Base)传递参数__a

如果你能以某种方式"扩大"typedef的范围,并写下:

1
2
3
4
5
6
7
8
9
10
11
template <class _Tp, class _Alloc>                                      
class _List_base                                                        
  : public _Base
{                                                                      
public:                                                                
  typedef _List_alloc_base<_Tp, _Alloc,                                
                           _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
          _Base;
  typedef typename _Base::allocator_type allocator_type;                

  _List_base(const allocator_type& __a) : _Base(__a) {

它用于根据以前存在的类型定义自定义类型。为您可能会说的类型提供别名。typedef可以理解为"define type"或"typedefinition"。

您可以"链接"typdefs,即:

1
2
3
typedef int Id;     // Define new type"Id"
typedef Id UserId;  // Define new type"UserId" based on a previously existing type
// This is possible since"Id" was already defined

然后使用它:

1
UserId uid = 0; //uid is a variable of type UserId, which is an alias for int

在您每次使用_Base时提供的示例中,您在发动机罩下使用_List_alloc_base<_Tp, _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless>,但使用的方式较短。使用该别名可以得到更干净、更紧凑的代码块。

您可能会注意到该示例在以下行中也使用了typedef typename

1
typedef typename _Base::allocator_type allocator_type;

注意,该行中可以使用_Base,因为它已经在前一行中定义了。关于typedeftypename的联合使用,请参阅本问题,并阅读本答案。


从这个链接:

The formula to follow is:

typedef [attributes] DataType AliasName;

The typedef keyword is required. The attribute is not.
The typedef keyword can be followed by any C++ built-in data type, including int, short, signed, unsigned, char, signed char, unsigned char, double, long, or long double. The data type can also be an existing class that either is provided by one of the libraries that ship with the C++ compiler. For example, it can be the string class. The data type can also be a pointer to a known type.

尽管这是一个定义,你会遇到很多次为这个关键字,它可能更容易认为它是typedef declaration;,如马特奥意大利在下面的评论指出。