before_begin实现forward_list

时间:2015-03-25 22:08:42

标签: c++11 forward-list

before_begin方法在std::forward_list的上下文中是如何实现的?

我尝试过这样的事情:

template <class _Tp>
typename forward_list<_Tp>::iterator forward_list<_Tp>::before_begin() NOEXCEPT {
  return forward_list_iterator<_Tp>(new forward_list_node<_Tp>(_Tp(), m_pHead));
}

template <class _Tp>
typename forward_list<_Tp>::const_iterator forward_list<_Tp>::before_begin() const NOEXCEPT {
  return forward_list_const_iterator<_Tp>(new forward_list_node<_Tp>(_Tp(), m_pHead));
}

我理解的是,在调用before_begin insert_after等时应使用emplace_after方法。因此,我使该方法返回iterator到指向新节点的点至m_pHead并具有模板类型_Tp的默认值。但是,我不确定两件事:

1)当我使用模板时,如何获取默认值? _Tp()是一个合法的表达式,以获取特定类型的默认值(包括原始类型和用户定义的类型)?

2)由于此方法在iterator之前返回m_pHead,如果我使用insert_after作为第一个参数调用其中一个before_begin重载方法,那么我不会最终将数据插入列表中,但没有更新m_pHead

insert_after的四个重载之一的实现如下:

template <class _Tp>
void forward_list<_Tp>::insert_after(const_iterator _position, const _Tp& _value) {
  forward_list_node<_Tp>* _node = new forward_list_node<_Tp>(_value, _position.m_pNode->m_pNext);
  _position.m_pNode->m_pNext = _node;
}

非常感谢您抽出宝贵时间。 :)

编辑:根据T.C.答案链接中的代码,before_begin应该像这样实现:

iterator before_begin() { return iterator(&head); }

但是,这就是我begin的实施方式:

template <class _Tp>
typename forward_list<_Tp>::iterator forward_list<_Tp>::begin() NOEXCEPT {
  return forward_list_iterator<_Tp>(m_pHead);
}

我真的不知道上面的before_begin实现应该如何工作(或者我的insert_after没有正确写入)。

编辑2:根据我的理解,到目前为止,before_begin应该返回m_pHeadbegin应该返回m_pHead->m_pNext。这实际上并不多感觉,因为begin应隐含地引用m_pHead,但我认为这是一种解决方法。

1 个答案:

答案 0 :(得分:2)

基本理念是:

struct node_base {
    node_base * next;
};

template<class T>
struct node : node_base {
    T value;
};

template<class T>
struct forward_list_iter {
    forward_list_iter(node_base *pn) : pnode(pn) { }
    T& operator*() const { return static_cast<node<T>*>(pnode)->value; }
    forward_list_iter& operator++() { pnode = pnode->next; return *this; }
    // other stuff
    node_base* pnode;
};

template<class T>
struct forward_list {
    node_base head;
    forward_list_iter<T> before_begin() { 
        return forward_list_iter<T>(&head); 
    }
    forward_list_iter<T> begin() { 
        return forward_list_iter<T>(head.next); 
    }
    // other stuff
};

head节点嵌入forward_list本身,只是一个node_base,它只包含指向下一个节点的指针。所有其他节点实际上是node<T> s,它派生自node_base并存储类型T的值。迭代器存储node_base *,并在取消引用时将其强制转换为node<T> *before_begin()指向head; begin()指向head.next,这实际上是第一个包含值的节点。