tags:

views:

115

answers:

1

Can anyone explain why the _List_const_iterator would be using _List_node_base and downcast it to _List_node when needed? -- I think there must be some reason behind this.

Thanks

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?
};
+2  A: 

I'm guessing that _M_node is of type _List_node_base* so that it can be assigned/initialized using _M_next and/or _M_prev (which as you've shown are of type _List_node_base*).

I wonder why there's a _List_node_base class at all, instead of declaring _M_next and _M_prev as members of the _List_node class. One reason might be to reduce the amount of generated code: if you have many different specializations of the _List_node class, having most (if not all) of its code/implementation in a non-generic base class reduces the amount of generated code.

ChrisW
+1: Preventing code duplication is exactly why it's done. It says so in the comments just above the definition of `_List_node_base` in the STL header I have on my system.
Troubadour