关于 C++ 的问题模板语法(STL库源代码)
我现在正在阅读STL源代码。 虽然我理解我在 stl_list.h 中阅读的内容,但我想完全理解以下代码片段(我认为主要与模板语法相关)。
template
class _List_base {
...
typedef typename _Alloc::template rebind<_List_node<_Tp> >::other _Node_Alloc_type; //(1).
...
typedef _Alloc allocator_type;
get_allocator() const
{ return allocator_type(*static_cast<
const _Node_Alloc_type*>(&this->_M_impl)); } // (2)
...
};
有人能解释一下为什么我们在第 (1) 行的 _Alloc 之后需要一个“模板”吗? (并给出这一行的完整解释?)
有人可以解释为什么我们可以在第(2)行中将 _Node_Alloc_type 转换为 _Alloc 吗?
I am reading STL source code right now.
Though I understand the meat in what I am reading in stl_list.h, I want to fully understand the following snippet (mainly related to the template syntax, I think).
template
class _List_base {
...
typedef typename _Alloc::template rebind<_List_node<_Tp> >::other _Node_Alloc_type; //(1).
...
typedef _Alloc allocator_type;
get_allocator() const
{ return allocator_type(*static_cast<
const _Node_Alloc_type*>(&this->_M_impl)); } // (2)
...
};
Can someone explain why we need a "template" following _Alloc in line (1)? (and giving a full explanation of this line?)
Can someone explain why we can cast _Node_Alloc_type to _Alloc in line (2)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
需要
template
关键字将名称rebind
标识为类模板。如果没有它,rebind
可以被视为变量或常量(在本例中是由于typename
关键字而产生的类型)以及以下<
可以被解释为小于运算符。这有点类似于
typename
关键字(这当然是将other
识别为类型所必需的)。每个分配器都需要提供一个名为“rebind”的元函数(即类模板),它返回相同的分配器,但类型不同。换句话说,
在没有更多上下文的情况下,将与问题的第二部分命名相同的类型
很难回答。
_M_impl
的类型是什么?该类型是如何定义的?The
template
keyword is needed to identify the namerebind
as a class template. Without it,rebind
could be considered a variable or a constant (in this case a type due to thetypename
keyword) and the following<
could be interpreted as a less-than operator.This is somewhat similar to the
typename
keyword (which is of course necessary to identifyother
as a type).Every allocator is required to provide a meta-function (i.e. a class template) called
rebind
that returns the same allocator but for a different type. In other words,names the same type as
The second part of your question is difficult to answer without more context. What is the type of
_M_impl
? How is that type defined?它看起来像 std::list 的 gcc 实现。在这种情况下,上下文是:
并且你忘记写成员函数的返回类型:
回答(1)
当在
_Tp
类型的列表中添加节点时,真正需要分配的是什么不是对象_Tp
,而是包含_Tp
的列表节点(_List_node<_Tp>
)。因此 std::list 需要能够分配
_List_node<_Tp>
,但它已为_Tp
提供了分配器。这就是模板 typedef rebind 派上用场的地方:它使得可以从类型 T 的分配器中获取类型 U 的分配器。使用此重新绑定,我们得到一个
_Alloc<_List_node<_Tp>; >
来自类型_Alloc<_Tp>
。源文件中对 (2) 的回答作为注释:
假设
_Alloc
的类型与 C++ 标准中的_Node_Alloc_type
相同;因此 static_cast 断言转换是合法的。It looks like the gcc implementation of std::list. In that case, the context is:
And you forgot to write the return type of the member function:
Answer for (1)
When adding a node in a list of type
_Tp
, what really needs to be allocated is not an object_Tp
but a list node containing_Tp
(a_List_node<_Tp>
).So the std::list needs to be able allocate a
_List_node<_Tp>
but it has been provided an allocator for_Tp
. This is where the template typedef rebind comes in handy: it makes it possible to get an allocator for type U from an allocator for type T.Using this rebind, we get an
_Alloc<_List_node<_Tp> >
from the type_Alloc<_Tp>
.Answer for (2) in the source file as comment:
It is assumed that
_Alloc
's type is the same as_Node_Alloc_type
as per the C++ Standard; hence the static_cast asserts the conversion is legal.