简体   繁体   中英

Nested template class constructor

I the compiler can't find the definition of my constructor for the nested class.

My nested class Node is in the middle and the constructor is at the end.

Errors:

error C2244: 'CircularDoubleDirectedList::Node::Node' : unable to match function definition to an existing declaration see declaration of 'CircularDoubleDirectedList::Node::Node'

definition

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

existing declarations

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

Code:

#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

First, the forward-declared template <typename T> class Node; is not the same as CircularDoubleDirectedList::Node - the former is a global class template, the latter is a nested class.

Second, you don't need to declare CircularDoubleDirectedList::Node as a template (and if you do, you have to use another template parameter name for it, not T ). But as I understand, for this case you should just make it non-template, so:

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;
}

You have two class templates named Node , while in reality you want one non-template class named Node . You have forward-declared ::Node<T> , and you have the nested ::CircularDoubleDirectedList<T>::Node<U> .

If you really want it like that, you'll have to add another template keyword to the constructor definition:

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)
{}

However, I can't see a single reason to have Node be a template. Inside CircularDoubleDirectedList<T> , do you want to use nodes with type other than T ? If not, make Node a normal non-template class:

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)
{}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM