Проблема с шаблонами

183
03 февраля 2020, 10:10

Скажите пожалуйста, почему у меня не получается реализацию интерфейсов с шаблонами сделать?

Queue.h

#ifndef UNTITLED104_QUEUE_H
#define UNTITLED104_QUEUE_H
#include <vector>
#include <cstdio>
using namespace std;
template <typename T>
class Node{
private:
    T value;
public:
    Node *next_node, *back_node;
    Node():next_node(NULL),back_node(NULL){};
    Node(T new_value):value(new_value),next_node(NULL),back_node(NULL){};
    T getValue();
    void setValue(T new_value);
    void deleteNode();
    Node* getNext();
    Node* getBack();
};
template <typename T>
class Queue{
private:
    Node<T>* firstNode=NULL;
    unsigned size=0;
public:
    Queue(T value);
    Node<T>* getFirst();
    Node<T>* getNode(int position);
    unsigned int getSize();
    Node<T>* insert_after(int position, T value);
};
#endif //UNTITLED104_QUEUE_H

Queue.cpp

#include "Queue.h"
template<typename T>
T Node<T>::getValue() {
    return nullptr;
}
template<typename T>
void Node<T>::setValue(T new_value) {
}
template<typename T>
void Node<T>::deleteNode() {
}
template<typename T>
Node *Node<T>::getNext() {
    return nullptr;
}
template<typename T>
Node *Node<T>::getBack() {
    return nullptr;
}


template<typename T>
Queue<T>::Queue(T value) {
}
template<typename T>
Node<T> *Queue<T>::getFirst() {
    return nullptr;
}
template<typename T>
Node<T> *Queue<T>::getNode(int position) {
    return nullptr;
}
template<typename T>
unsigned int Queue<T>::getSize() {
    return 0;
}
template<typename T>
Node<T> *Queue<T>::insert_after(int position, T value) {
    return nullptr;
}

Ошибки:

C:\Users\Alex\CLionProjects\untitled104\Queue.cpp:21:1: error: invalid use of template-name 'Node' without an argument list
 Node *Node<T>::getNext() {
 ^
C:\Users\Alex\CLionProjects\untitled104\Queue.cpp:26:1: error: invalid use of template-name 'Node' without an argument list
 Node *Node<T>::getBack() {
 ^
Answer 1

Просто Node является синонимом Node<T> только в области видимости класса. За пределами этой области видимости придется всегда использовать "полный" синтаксис Node<список аргументов шаблона>.

Если определение метода шаблона Node<T> делается за пределами шаблонного класса, то по вышеприведенной причине в типе возвращаемого значения вы уже не сможете сокращать Node<T> до Node при использовании "классического" синтаксиса. Правильно

template<typename T>
Node<T> *Node<T>::getNext() {
    return nullptr;
}

Однако если спецификация шаблонного типа длинна и вы не хотите повторять ее дважды, вы можете воспользоваться новым синтаксисом

template<typename T>
auto Node<T>::getNext() -> Node * {
    return nullptr;
}

В этом случае вы можете использовать справа "короткое" имя Node.

И, как вам уже сказали, определения шаблонных сущностей не следует выносить в .cpp файл. Даже если вы делаете их за пределами класса, то их все равно следует поместить в заголовочный файл, рядом с определением класса.

Дополнительная ; после определения метода в классе

Node():next_node(NULL),back_node(NULL){};
                                        ^

не является ошибкой, но является ненужным пустым объявлением.

Также не ясно, почему в одном классе вы пользуетесь инициализаторами для полей прямо в определении класса, а в другом упорно отказываетесь.

Answer 2

Ошибка возникает из-за того, что классу Node не хватает аргумента шаблона. Исправьте тип полей next_node и back_node на Node<T> *, а также возвращаемый тип методов getNext и getBack.

Answer 3

Во-первых, следует поместить полностью определения шаблонных классов (включая их членов) в заголовок.

Во-вторых, в некоторых функциях вы забыли определить шаблонный идентификатор.

template<typename T>
Node<T> * Node<T>::getNext() 
{
    return nullptr;
}
template <typename T>
Node<T> * Node<T>::getBack() 
{
    return nullptr;
}

Ниже представлен заголовок с соответствующими внесенными изменениями.

#ifndef UNTITLED104_QUEUE_H
#define UNTITLED104_QUEUE_H
#include <vector>
#include <cstdio>
using namespace std;
template <typename T>
class Node
{
private:
    T value;
public:
    Node *next_node, *back_node;
    Node() : next_node( nullptr ),back_node( nullptr )
    {
    }
    Node( const T &new_value ) : value( new_value ), next_node( nullptr ), back_node( nullptr )
    {
    }
    T getValue() const;
    void setValue( const T &new_value );
    void deleteNode();
    Node* getNext();
    Node* getBack();
};
template <typename T>
class Queue{
private:
    Node<T>* firstNode = nullptr;
    size_t size = 0;
public:
    Queue( const T &value );
    Node<T> * getFirst();
    Node<T> * getNode( size_t position );
    size_t getSize() const;
    Node<T> * insert_after( size_t position, const T &value );
};
template <typename T>
T Node<T>::getValue() const
{
    return nullptr;
}
template <typename T>
void Node<T>::setValue( const T &new_value ) 
{
}
template <typename T>
void Node<T>::deleteNode() 
{
}
template<typename T>
Node<T> * Node<T>::getNext() 
{
    return nullptr;
}
template <typename T>
Node<T> * Node<T>::getBack() 
{
    return nullptr;
}

template <typename T>
Queue<T>::Queue( const T &value ) 
{
}
template <typename T>
Node<T> * Queue<T>::getFirst() 
{
    return nullptr;
}
template <typename T>
Node<T> * Queue<T>::getNode( size_t position ) 
{
    return nullptr;
}
template <typename T>
size_t Queue<T>::getSize() const 
{
    return 0;
}
template <typename T>
Node<T> * Queue<T>::insert_after( size_t position, const T &value ) 
{
    return nullptr;
}
#endif //UNTITLED104_QUEUE_H
READ ALSO
Перевод в big-endian, проблемы с данными типа signed

Перевод в big-endian, проблемы с данными типа signed

Прошу помощи со следующим вопросомИмеется бинарный файл, достаточно большой

185
QMapControl проблема с яндекс картами

QMapControl проблема с яндекс картами

Захотелось отображать яндекс карты в QMapControl, для этого создал yandexMapAdapter

161
Настройка включения библиотек для cxxtest [закрыт]

Настройка включения библиотек для cxxtest [закрыт]

Хотите улучшить этот вопрос? Переформулируйте вопрос, чтобы он соответствовал тематике «Stack Overflow на русском»

183
эхоподавление на с++

эхоподавление на с++

Реализую небольшой проект по воспроизведении аудио данных, в том числе и с микрофонаДля воспроизведения пользуюсь библиотекой soundiolib, библиотека...

166