Doubly Linked List默认typename节点

时间:2015-07-12 19:29:43

标签: c++ list templates c++11

我正在编写一个简单的双链表,如下所示:

Node.h

#pragma once

template<typename T>
class Node
{
public:
    Node() : _next(nullptr), _prev(nullptr) {}
    Node(Node* next, Node* prev, T data) : _next(next), _prev(prev), _data(data) {}

    Node* Next() { return _next; }
    Node* Prev() { return _prev; }
    T  Source() { return _data; }

    Node* _next;
    Node* _prev;
    T   _data;
};

DLList.h

#include "Node.h"

template<typename T>
class DLList
{
public:
    DLList() : _head(nullptr) {}

    Node<T>* AddNode(T val)
    {
        Node<T>* m_prev = _head;

        Node<T>* m_node = new Node<T>(nullptr, m_prev, val);
        if (m_prev)
            m_prev->_next = m_node; 
        _head = m_node;
        return m_node;
    }

    Node<T>* First()
    {
        Node<T>* m_node = _head;
        while (m_node->Prev()) { m_node = m_node->Prev(); }
        return m_node;
    }

    Node<T>* Last()
    {
        return _head;
    }
private:
    Node<T>* _head;
};

现在我已经用它进行了一些测试,它们都很好,测试如下:

#include "DLList.h"

using namespace std;

int main(int argc, char** argv)
{
    DLList<int> testList;
    for (int i = 0; i < 10; i++)
        testList.AddNode(i * 10);

    Node<int>* node = testList.First();
    do{
        cout << "value of node : " << node->Source() << endl;
    } while (node = node->Next());

    Node<int>* end = testList.Last();
    do{
        cout << "value of node : " << end->Source() << endl;
    } while (end = end->Prev());
    cin.get();
    return 0;
}

我的问题是,每次我必须声明Node指针以获取列表中的第一个或最后一个Node时,我必须这样做: Node<int>* end = testList.Last();Node<int>* node = testList.First();。 由于我的列表已经知道类型TFirst()Last()的可能实现,我可以Node* node = testList.First();Node* end = testList.Last();而不是必须提供模板参数?

2 个答案:

答案 0 :(得分:3)

  

“由于我的列表已经知道类型T,可能会实现First()Last(),我可以Node* node = testList.First();或{{1} }?“

不,您不能,但您可以使用Node* end = testList.Last();关键字,让编译器推断出实际类型:

auto

答案 1 :(得分:1)

我个人不会直接暴露Node。

我会暴露一个在类内部定义的Iterator类型(如果恰好是引擎盖下的Node那么好。)

template<typename T>
class DLList
{
public:
    DLList() : _head(nullptr) {}

    typedef  Node<T>        iterator;
    typedef  Node<const T>  const_iterator;

    T&       First();      // would not expose a node here.
    T const& First() const;// I would return the first value in the list.

    iterator       begin();      // Iterator to first element.
    const_iterator begin() const;

    ....

现在你可以使用自动技巧来阻止你过于准确地指定事物了。

int main()
{
    DLList<int>     data;
    // Add data.

    auto it = data.begin();