嵌套模板类构造函数

Nested template class constructor

本文关键字:构造函数 嵌套      更新时间:2023-10-16

编译器找不到嵌套类的构造函数的定义。

我的嵌套类节点在中间,构造函数在最后。

错误:

错误 C2244:"循环双定向列表::节点::节点":无法要将函数定义与现有声明匹配,请参阅声明"循环双定向列表::节点::节点"

定义

'CircularDoubleDirectedList::Node::Node(const T &)'

现有声明

'CircularDoubleDirectedList::Node::Node(const T &)'

法典:

#ifndef CIRCULARDOUBLEDIRECTEDLIST_H
#define CIRCULARDOUBLEDIRECTEDLIST_H
#include "ICircularDoubleDirectedList.h"
template <typename T> class CircularDoubleDirectedList;
template <typename T> class Node;
template <typename T>
class CircularDoubleDirectedList :
    public ICircularDoubleDirectedList<T>{
public:
    //Variabels
    Node<T>* current;
    int nrOfElements;
    direction currentDirection;
    //Functions
    CircularDoubleDirectedList();
    ~CircularDoubleDirectedList();
    void addAtCurrent(const T& element) override;
private:
    template <typename T>
    class Node
    {
    public:
        T data;
        Node<T>* forward;
        Node<T>* backward;
        Node(const T& element);// The constructor
    };
};
template <typename T>
CircularDoubleDirectedList<T>::CircularDoubleDirectedList(){
    this->nrOfElements = 0;
    this->current = nullptr;
    this->currentDirection = FORWARD;
}
template <typename T>
CircularDoubleDirectedList<T>::~CircularDoubleDirectedList(){
    //TODO: Destroy all nodes
}
template <typename T>
void CircularDoubleDirectedList<T>::addAtCurrent(const T& element){
    Node<T>* newNode = new Node<T>(element);
    newNode->data = element;
    if (this->nrOfElements == 0){
        newNode->forward = newNode;
        newNode->backward = newNode;
    }
    else{
        //this->current->forward = newNode;
        //this->current->forward->backward = newNode;
    }
    //this->current = newNode;
}
template <typename T>
CircularDoubleDirectedList<T>::Node<T>::Node(const T& element){
    this->data = element;
}
#endif

首先,前向声明的template <typename T> class Node;CircularDoubleDirectedList::Node不同 - 前者是全局类模板,后者是嵌套类。

其次,您不需要将CircularDoubleDirectedList::Node声明为模板(如果这样做,则必须为其使用另一个模板参数名称,而不是T)。但据我了解,在这种情况下,您应该将其设置为非模板,因此:

template <typename T>
class CircularDoubleDirectedList :
    public ICircularDoubleDirectedList<T>{
private:
    class Node
    {
    public:
        T data;
        Node* forward;
        Node* backward;
        Node(const T& element);// The constructor
    };
public:
    Node* current;
    //...
};
template <typename T>
CircularDoubleDirectedList<T>::Node::Node(const T& element){
    this->data = element;
}

您有两个名为 Node 的类模板,而实际上您需要一个名为 Node 的非模板类。您有前向声明的::Node<T> ,并且您有嵌套的::CircularDoubleDirectedList<T>::Node<U>

如果你真的想要这样,你必须在构造函数定义中添加另一个template关键字:

template <typename T>  //because CircularDoubleDirectedList is a template
template <typename U>  //because Node is a template
CircularDoubleDirectedList<T>::Node<U>::Node(const T& element) : data(element)
{}

但是,我看不出让Node成为模板的单一理由。在CircularDoubleDirectedList<T>内部,是否要使用类型不是T的节点?如果没有,请将Node设为普通的非模板类:

template <typename T>
class CircularDoubleDirectedList :
    public ICircularDoubleDirectedList<T>{
public:
    //Variabels
    Node<T>* current;
    int nrOfElements;
    direction currentDirection;
    //Functions
    CircularDoubleDirectedList();
    ~CircularDoubleDirectedList();
    void addAtCurrent(const T& element) override;
private:
    class Node
    {
    public:
        T data;
        Node* forward;
        Node* backward;
        Node(const T& element);// The constructor
    };
};

template <typename T>
CircularDoubleDirectedList<T>::Node::Node(const T& element) : data(element)
{}