有人可以解释为什么_List_const_iterator会使用_List_node_base并在需要时将其向下转换为_List_node吗? - 我认为这背后肯定有一些原因。
由于
struct _List_node_base
{
_List_node_base* _M_next; ///< Self-explanatory
_List_node_base* _M_prev; ///< Self-explanatory
// ...
};
template<typename _Tp>
struct _List_node : public _List_node_base
{
_Tp _M_data; ///< User's data.
};
template<typename _Tp>
struct _List_const_iterator {
// Must downcast from List_node_base to _List_node to get to
// _M_data.
reference operator*() const
{ return static_cast<_Node*>(_M_node)->_M_data; }
// ...
// The only member points to the %list element.
const _List_node_base* _M_node; ///WHY NOT USING _List_node here?
};
答案 0 :(得分:2)
我猜测_M_node
属于_List_node_base*
类型,因此可以使用_M_next
和/或_M_prev
分配/初始化它(如您所示)属于_List_node_base*
)类型。
我想知道为什么会有_List_node_base
类,而不是将_M_next
和_M_prev
声明为_List_node
类的成员。一个原因可能是减少生成的代码量:如果您有_List_node
类的许多不同的特化,那么在非泛型基类中拥有大多数(如果不是全部)代码/实现会减少生成的代码。
答案 1 :(得分:1)
这是来自EASTL list.h实施的评论 -
/// ListNodeBase
///
/// We define a ListNodeBase separately from ListNode (below), because it allows
/// us to have non-templated operations such as insert, remove (below), and it
/// makes it so that the list anchor node doesn't carry a T with it, which would
/// waste space and possibly lead to surprising the user due to extra Ts existing
/// that the user didn't explicitly create. The downside to all of this is that
/// it makes debug viewing of a list harder, given that the node pointers are of
/// type ListNodeBase and not ListNode. However, see ListNodeBaseProxy below.
///