当我阅读stdc ++代码时,我对以下几行感到困惑。 这是stl_list.h中的一段代码。
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
出现在初始化列表中。
我该如何理解这种用法?或者你请为我粘贴一些有用的链接。
答案 0 :(得分:1)
它用于根据以前存在的类型定义自定义类型。为您提供的类型提供别名。 typedef
可以理解为“定义类型”或“type
- def
inition”。
你可以拥有“链式”typdef
s,即:
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
然后使用它:
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
:
typedef typename _Base::allocator_type allocator_type;
请注意_Base
可以在该行中使用,因为它已在上一行中定义。有关typedef
和typename
合并使用的说明,请参阅this question,同时阅读this answer。
来自this link:
要遵循的公式是:
typedef [attributes] DataType AliasName;
typedef
关键字是必需的。 属性不是。typedef
关键字可以跟随任何C ++内置数据类型,包括int
,short
,signed
,unsigned
,char
,signed char
,unsigned char
,double
,long
或long double
。数据类型也可以是现有的类,它由C ++编译器附带的库之一提供。例如,它可以是字符串类。数据类型也可以是指向已知类型的指针。
即使这是一个定义,您会多次遇到此关键字,但可能更容易将其视为{em>意大利在下面的评论中指出的typedef declaration;
。
答案 1 :(得分:1)
typedef
声明类型的别名 - 如果您愿意,可以使用简写。
它的语法就像你声明一个变量一样,但它代替了一个变量,它为指定的类型创建了一个别名:
int a; // a is a variable of type int
typedef int B; // B is an alias for type int
(请注意,他们经常会说typedef original-type alias
,但这是一个不正确的规则 - 例如,如果函数指针失败了 - 而且还有一条规则无缘无故地记住了< / p>
对于静态成员,类型别名是作用域 - 在类中可以访问它而没有其他限定符,从外部它需要限定(_List_base::_Base
)。
根据您的具体情况,它只是引用基类的简写,即_List_alloc_base<_Tp, _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
,并且每次完全写入都非常麻烦。
它出现在初始化列表中,因为构造函数正在调用基类的构造函数 - 即_Base
- 传递参数__a
。
如果你能以某种方式,这可能更容易看到&#34;放大&#34; typedef
的范围并写:
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) {