Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何为单列表和双列表节点c++;_C++_Templates_Inheritance - Fatal编程技术网

C++ 如何为单列表和双列表节点c++;

C++ 如何为单列表和双列表节点c++;,c++,templates,inheritance,C++,Templates,Inheritance,我只想实现两种类型的节点(仅限节点): 单链表的节点和双链表的节点类。 显而易见的解决方案是定义两个单独的类: template <typename T> struct SinglyNode { using node_pointer = SinglyNode<T>*; SinglyNode(T data = T{}, node_pointer next = nullptr) : m_data{ data }, m_next{

我只想实现两种类型的节点(仅限节点):
单链表的节点和双链表的节点类。
显而易见的解决方案是定义两个单独的类:

template <typename T>
struct SinglyNode
{
    using node_pointer = SinglyNode<T>*;
    SinglyNode(T data = T{}, node_pointer next = nullptr)
        : m_data{ data },
        m_next{ next }
    {}
    T m_data;
    node_pointer m_next;
};

template <typename T>
struct DoublyNode
{
    using node_pointer = DoublyNode<T>*;
    DoublyNode(T data = T{}, node_pointer prev = nullptr, node_pointer next = nullptr)
        : m_data{ data },
        m_prev { prev },
        m_next{ next }
    {}
    T m_data;
    node_pointer m_prev;
    node_pointer m_next;
};
模板
结构单节点
{
使用node_pointer=SinglyNode*;
SinglyNode(T data=T{},node_pointer next=nullptr)
:m_data{data},
m_next{next}
{}
T m_数据;
节点\指针m \下一步;
};
模板
结构双连节点
{
使用node_pointer=DoublyNode*;
DoublyNode(T data=T{},node_pointer prev=nullptr,node_pointer next=nullptr)
:m_data{data},
m_prev{prev},
m_next{next}
{}
T m_数据;
节点指针m_prev;
节点\指针m \下一步;
};
我知道DoublyNode和SinglyNode都有数据,并链接到下一个节点(节点的类型不同,SinglyNode::m_next的类型是SinglyNode*,DoublyNode::m_next的类型是DoublyNode*), 此外,DoublyNode还具有到上一个节点的链接

但是,我如何创建一个层次结构来删除/最小化代码重复,以便用户可以使用派生类成员,而不需要动态地转换到派生节点


注意:一段代码片段或一些提示对我来说就足够了。

使用CRTP,您可以执行以下操作:

template <typename Derived, typename T>
struct SinglyNodeCRTP
{
    using node_pointer = Derived*;
    SinglyNodeCRTP(T data = T{}, node_pointer next = nullptr)
        : m_data{ data },
        m_next{ next }
    {}
    T m_data;
    node_pointer m_next;
};


template <typename T>
struct SinglyNode : SinglyNodeCRTP<SinglyNode<T>, T>
{
    using SinglyNodeCRTP::SinglyNodeCRTP;
};

template <typename T>
struct DoublyNode : SinglyNodeCRTP<DoublyNode<T>, T>
{
    using node_pointer = typename SinglyNodeCRTP<DoublyNode<T>, T>::node_pointer;
    DoublyNode(T data = T{}, node_pointer prev = nullptr, node_pointer next = nullptr)
        : SinglyNodeCRTP<DoublyNode<T>, T>{ data , prev },
        m_prev{ prev }
    {}
    node_pointer m_prev;
};
模板
结构SinglyNodeCRTP
{
使用节点_指针=派生*;
SinglyNodeCRTP(T data=T{},node_pointer next=nullptr)
:m_data{data},
m_next{next}
{}
T m_数据;
节点\指针m \下一步;
};
模板
结构SinglyNode:SinglyNodeCRTP
{
使用SinglyNodeCRTP::SinglyNodeCRTP;
};
模板
结构DoublyNode:SinglyNodeCRTP
{
使用node_pointer=typename SinglyNodeCRTP::node_pointer;
DoublyNode(T data=T{},node_pointer prev=nullptr,node_pointer next=nullptr)
:SinglyNodeCRTP{data,prev},
m_prev{prev}
{}
节点指针m_prev;
};

获得问题答案后的最后代码

      template <typename N, typename T>
      struct node_base {
        T m_value;
        N* m_next;
        node_base(T value = T{}, N* next = T{})
            : m_value{ value },
            m_next{ next }
        {}
      };

      template <typename T>
      struct snode : public node_base<snode<T>, T>
      {
          using node_base::node_base;
      };

      template <typename T>
      struct dnode : public node_base<dnode<T>, T>
      {
        using node_type = dnode<T>;
        dnode(T value = T{}, node_type* prev = nullptr, node_type* next = nullptr)
            : node_base<node_type, T>{ value, next },
            m_prev{prev}
        {}
        dnode<T>* m_prev;
      };
模板
结构节点库{
T m_值;
N*m_下一步;
node_base(T value=T{},N*next=T{})
:m_值{value},
m_next{next}
{}
};
模板
结构节点:公共节点\u基
{
使用node_base::node_base;
};
模板
struct dnode:公共节点\u基
{
使用node_type=dnode;
dnode(T值=T{},节点类型*prev=nullptr,节点类型*next=nullptr)
:node_base{value,next},
m_prev{prev}
{}
dnode*m_prev;
};

“节点不属于同一类型”您需要澄清这一点。您发布的模板具有相同类型的节点,因为例如
node\u pointer=SinglyNode*@dxiv已编辑!!您可以派生
struct-DoublyNode:public-SinglyNode
,就像这样。或者像刚刚发布的答案一样,用CRTP更优雅地做。如果这就是您所说的“使用派生类成员而不需要动态_强制转换”的意思,那么您可以在问题中更清楚地说明这一点?。或者,您也可以使用
DoublyNode
。谢谢,我不知道CRTP和“构造函数继承”。