GCC compiler error when dealing with template classes 'error:invalid use of incomplete type template'
GCC compiler error when dealing with template classes 'error:invalid use of incomplete type template'
为了防止模板class的特殊化错误,我已经将某些class的声明和实现放在了list.h
文件中:
#ifndef _LIST_
#define _LIST_
#include <iostream>
#include <cstddef>
#define push() append();
#define pop() remove();
#define _DEBUG 1
template <class T>
class ListNode //Employee class
{
public:
#if _DEBUG
unsigned int index = 0; //Test only.
#endif
T data; //Can be replaced by any other types.
ListNode<T> *prev = NULL;
ListNode<T> *next = NULL;
public:
ListNode(int userInputData) : data(userInputData), prev(NULL), next(NULL){};
ListNode() : prev(NULL), next(NULL){};
};
template <class T>
using node = ListNode<T>;
template <class T>
class SINGLY_LINKED_LIST //Manager class
{
private:
ListNode<T> *head = NULL;
ListNode<T> *tail = NULL;
unsigned int len = 0;
public:
SINGLY_LINKED_LIST() : head(NULL), tail(NULL), len(0){}; //Void construct function.
SINGLY_LINKED_LIST(ListNode<T> *start_node, int userInputlength); //Init by a node and length.
bool print(void); //Print a list on screen.
int get_length(void); //Get the length of the whole list.
int get_length(ListNode<T> *start_node); //Get the length of a sub-list.(start from start_ndoe)
ListNode<T> *operator[](unsigned int N); //Access to the address(ptr) of node.
ListNode<T> *begin(void); //Return the head pointer of list.
ListNode<T> *end(void); //Return the tail pointer of list.
bool remove(void); //Remove last node->pop().
bool remove(ListNode<T> *start_node); //Remove a chosen node.
bool remove(int N); //Remove a node that 'N' blocks from the head_node.
bool remove(ListNode<T> *start_node, int N); //Remove a node that 'N' blocks from the start_node(reference argument).
int remove(bool (*cmp)(int stock_val, int input_val), int input_val); //Remove node match the value,return num.
bool destroy(void); //Destroy the whole list.
bool destroy(ListNode<T> *start_node, ListNode<T> *end_node); //Destroy a part of the list.(destroy a sub-list by start_node to end_node)
ListNode<T> *push_back(void); //Add back a new node<T>.
ListNode<T> *push_back(unsigned int num); //Add back a dozen of nodes.
ListNode<T> *push_back(ListNode<T> *add_node); //Add back a selected node(pointer).
ListNode<T> *push_front(unsigned int num); //Add several node at front.
ListNode<T> *push_front(void); //Add a node at front.
ListNode<T> *insert(ListNode<T> *position); //Insert one node(by default)at position.
ListNode<T> *insert(ListNode<T> *position, unsigned int num); //Insert several node at posotion.
ListNode<T> *insert(ListNode<T> *position, ListNode<T> *chosen_node); //Insert a chosen node at position.
ListNode<T> *find(bool (*cmp)(int stock_val, int input_val), int input_val); //Find the first element equal to 'input_val'.
};
template <class T>
using SLL = SINGLY_LINKED_LIST<T>;
template <class T>
SLL<T>::SINGLY_LINKED_LIST(ListNode<T> *start_node, int userInputlength) : len(userInputlength)
{
if (start_node->next == NULL && userInputlength >= 2)
{
this->head = start_node; //Save the head one address.
ListNode<T> *p = head;
for (int i = 1; i < userInputlength; i++)
{
p->next = new ListNode<T>;
p = p->next;
p->index = i;
p->data = i; //for test only.
p->next = NULL;
}
this->tail = p; //Save the last one address.
}
else
{
if (start_node->next == NULL)
{
std::cout << "[Error] List short or equal to '1'" << '\n';
}
else
{
std::cout << "[Error] This node has been in a list already!" << '\n';
}
}
}
template <class T>
ListNode<T> *SLL<T>::operator[](unsigned int N)
{
if (N < this->len)
{
ListNode<T> *p = this->head;
for (int i = 0; i < N; i++)
{
p = p->next;
}
return p;
}
else
{
std::cout << "[Error] Size overflow!" << '\n';
return NULL;
}
}
以及 class SLL
的其他成员函数如下...
gcc 编译器然后说:
In file included from main.cpp:2:
list.h:78:72: error: invalid use of incomplete type 'class SINGLY_LINKED_LIST<T>'
SLL<T>::SINGLY_LINKED_LIST(ListNode<T> *start_node, int userInputlength) : len(userInputlength)
^
In file included from main.cpp:2:
list.h:31:7: note: declaration of 'class SINGLY_LINKED_LIST<T>'
class SINGLY_LINKED_LIST //Manager class
^~~~~~~~~~~~~~~~~~
In file included from main.cpp:2:
list.h:110:47: error: invalid use of incomplete type 'class SINGLY_LINKED_LIST<T>'
ListNode<T> *SLL<T>::operator[](unsigned int N)
^
In file included from main.cpp:2:
list.h:31:7: note: declaration of 'class SINGLY_LINKED_LIST<T>'
class SINGLY_LINKED_LIST //Manager class
g++
似乎对这个别名有问题(而 clang++
和 MSVC
接受它):
template <class T>
using SLL = SINGLY_LINKED_LIST<T>;
所以,放弃它并使用 SINGLY_LINKED_LIST<T>
代替:
template <class T>
SINGLY_LINKED_LIST<T>::SINGLY_LINKED_LIST(ListNode<T> *start_node, int userInputlength)
和
template <class T>
ListNode<T> *SINGLY_LINKED_LIST<T>::operator[](unsigned int N)
为了防止模板class的特殊化错误,我已经将某些class的声明和实现放在了list.h
文件中:
#ifndef _LIST_
#define _LIST_
#include <iostream>
#include <cstddef>
#define push() append();
#define pop() remove();
#define _DEBUG 1
template <class T>
class ListNode //Employee class
{
public:
#if _DEBUG
unsigned int index = 0; //Test only.
#endif
T data; //Can be replaced by any other types.
ListNode<T> *prev = NULL;
ListNode<T> *next = NULL;
public:
ListNode(int userInputData) : data(userInputData), prev(NULL), next(NULL){};
ListNode() : prev(NULL), next(NULL){};
};
template <class T>
using node = ListNode<T>;
template <class T>
class SINGLY_LINKED_LIST //Manager class
{
private:
ListNode<T> *head = NULL;
ListNode<T> *tail = NULL;
unsigned int len = 0;
public:
SINGLY_LINKED_LIST() : head(NULL), tail(NULL), len(0){}; //Void construct function.
SINGLY_LINKED_LIST(ListNode<T> *start_node, int userInputlength); //Init by a node and length.
bool print(void); //Print a list on screen.
int get_length(void); //Get the length of the whole list.
int get_length(ListNode<T> *start_node); //Get the length of a sub-list.(start from start_ndoe)
ListNode<T> *operator[](unsigned int N); //Access to the address(ptr) of node.
ListNode<T> *begin(void); //Return the head pointer of list.
ListNode<T> *end(void); //Return the tail pointer of list.
bool remove(void); //Remove last node->pop().
bool remove(ListNode<T> *start_node); //Remove a chosen node.
bool remove(int N); //Remove a node that 'N' blocks from the head_node.
bool remove(ListNode<T> *start_node, int N); //Remove a node that 'N' blocks from the start_node(reference argument).
int remove(bool (*cmp)(int stock_val, int input_val), int input_val); //Remove node match the value,return num.
bool destroy(void); //Destroy the whole list.
bool destroy(ListNode<T> *start_node, ListNode<T> *end_node); //Destroy a part of the list.(destroy a sub-list by start_node to end_node)
ListNode<T> *push_back(void); //Add back a new node<T>.
ListNode<T> *push_back(unsigned int num); //Add back a dozen of nodes.
ListNode<T> *push_back(ListNode<T> *add_node); //Add back a selected node(pointer).
ListNode<T> *push_front(unsigned int num); //Add several node at front.
ListNode<T> *push_front(void); //Add a node at front.
ListNode<T> *insert(ListNode<T> *position); //Insert one node(by default)at position.
ListNode<T> *insert(ListNode<T> *position, unsigned int num); //Insert several node at posotion.
ListNode<T> *insert(ListNode<T> *position, ListNode<T> *chosen_node); //Insert a chosen node at position.
ListNode<T> *find(bool (*cmp)(int stock_val, int input_val), int input_val); //Find the first element equal to 'input_val'.
};
template <class T>
using SLL = SINGLY_LINKED_LIST<T>;
template <class T>
SLL<T>::SINGLY_LINKED_LIST(ListNode<T> *start_node, int userInputlength) : len(userInputlength)
{
if (start_node->next == NULL && userInputlength >= 2)
{
this->head = start_node; //Save the head one address.
ListNode<T> *p = head;
for (int i = 1; i < userInputlength; i++)
{
p->next = new ListNode<T>;
p = p->next;
p->index = i;
p->data = i; //for test only.
p->next = NULL;
}
this->tail = p; //Save the last one address.
}
else
{
if (start_node->next == NULL)
{
std::cout << "[Error] List short or equal to '1'" << '\n';
}
else
{
std::cout << "[Error] This node has been in a list already!" << '\n';
}
}
}
template <class T>
ListNode<T> *SLL<T>::operator[](unsigned int N)
{
if (N < this->len)
{
ListNode<T> *p = this->head;
for (int i = 0; i < N; i++)
{
p = p->next;
}
return p;
}
else
{
std::cout << "[Error] Size overflow!" << '\n';
return NULL;
}
}
以及 class SLL
的其他成员函数如下...
gcc 编译器然后说:
In file included from main.cpp:2:
list.h:78:72: error: invalid use of incomplete type 'class SINGLY_LINKED_LIST<T>'
SLL<T>::SINGLY_LINKED_LIST(ListNode<T> *start_node, int userInputlength) : len(userInputlength)
^
In file included from main.cpp:2:
list.h:31:7: note: declaration of 'class SINGLY_LINKED_LIST<T>'
class SINGLY_LINKED_LIST //Manager class
^~~~~~~~~~~~~~~~~~
In file included from main.cpp:2:
list.h:110:47: error: invalid use of incomplete type 'class SINGLY_LINKED_LIST<T>'
ListNode<T> *SLL<T>::operator[](unsigned int N)
^
In file included from main.cpp:2:
list.h:31:7: note: declaration of 'class SINGLY_LINKED_LIST<T>'
class SINGLY_LINKED_LIST //Manager class
g++
似乎对这个别名有问题(而 clang++
和 MSVC
接受它):
template <class T>
using SLL = SINGLY_LINKED_LIST<T>;
所以,放弃它并使用 SINGLY_LINKED_LIST<T>
代替:
template <class T>
SINGLY_LINKED_LIST<T>::SINGLY_LINKED_LIST(ListNode<T> *start_node, int userInputlength)
和
template <class T>
ListNode<T> *SINGLY_LINKED_LIST<T>::operator[](unsigned int N)