Why can't I declare "queue" for my class "linkedQueueType" in the main file

I am getting error in my main file:

linkedQueueType<char> queue;

undefined reference to `linkedQueueType<char>::linkedQueueType()'

Why can't I declare "queue" for my class "linkedQueueType" in the main file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  //Header File

    template<class Type>
    struct nodeType
    {
        Type info;
        nodeType<Type> * link;
    };
    
    template<class Type>
    class linkedQueueType
    {
    public:
        const linkedQueueType<Type>& operator=
                        (const linkedQueueType<Type>&);
        void initializeQueue();
        bool isEmptyQueue();
        bool isFullQueue();
        Type front();
        Type back();
        void addQueue(const Type& newItem);
        void deleteQueue();
        linkedQueueType();
        linkedQueueType(const linkedQueueType<Type>& otherQueue);
        ~linkedQueueType();
    private:
        nodeType<Type> * queueFront;
        nodeType<Type> * queueRear;
    };


.cpp file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
    //linkedQueueType.cpp
    #include "linkedQueueType.h"
    #include <iostream>
    using namespace std;
    
    //Default Constructor
    template<class Type>
    linkedQueueType<Type>::linkedQueueType()
    {
        queueFront = NULL; // set front to null
        queueRear = NULL; //set rear to null
    }
    
    //Destructor
    template<class Type>
    linkedQueueType<Type>::~linkedQueueType()
    {
        initializeQueue();
    }
    
    //EmptyQueue
    template<class Type>
    bool linkedQueueType<Type>::isEmptyQueue()
    {
        return(queueFront == NULL);
    }
    
    //FullQueue
    template<class Type>
    bool linkedQueueType<Type>::isFullQueue()
    {
        return false;
    }
    
    //initializeQueue
    template<class Type>
    void linkedQueueType<Type>::initializeQueue()
    {
        nodeType<Type> * temp;
    
        while(queueFront!= NULL) // while there are elements left in queue
        {
            temp = queueFront; //set temp to point to current node
            queueFront = queueFront->link; // advance first to next node
            delete temp; //deallocate memory occupied by temp
        }
    
        queueRear = NULL; // set rear to null
    }
    
    //addQueue
    template<class Type>
    void linkedQueueType<Type>::addQueue(const Type& newItem)
    {
        nodeType<Type> * newNode;
        newNode = new nodeType<Type>;
    
        newNode->info = newItem;
        newNode->link = NULL;
        if(queueFront == NULL)
        {
            queueFront = newNode;
            queueRear = newNode;
        }
        else
        {
            queueRear->link = newNode;
            queueRear = newNode;
        }
    }
    
    //deleteQueue
    template<class Type>
    void linkedQueueType<Type>::deleteQueue()
    {
        nodeType<Type> *temp;
    
        if(!isEmptyQueue())
        {
            temp = queueFront; //make temp  point to first node
            queueFront = queueFront->link; //advance queueFront
    
            delete temp; //delete first node
    
            if(queueFront == NULL) //if after deletion the queue is empty
                queueRear = NULL; //set queueRear to NULL
        }
        else
            cout << "Cannot remove from an empty queue" << endl;
    }
    
    //Front
    template<class Type>
    Type linkedQueueType<Type>::front()
    {
        return queueFront->info;
    }
    
    //Back
    template<class Type>
    Type linkedQueueType<Type>::back()
    {
        return queueRear->info;
    }

Last edited on
Template definitions need to be visible to the compiler when it compiles your main file. This is typically done by putting the definitions in the header.

Read this for other options: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file
Thank you, it is running now. That's really bizarre that it doesn't work in its own .cpp file because I'm linking the .cpp and header.
Remember, all source files are independently compiled by the compiler and then later linked together. This means that one source file will be completely compiled independently of another source file.

The reason it doesn't work in its own source file is because templates are instantiated by the compiler at COMPILE TIME. In order to instantiate it completely, it needs to see the entire definition of the template. When compiling a translation unit, all the template parameters are manually replaced with the template arguments. Thus, if the template definition is in a completely different translation unit, the compiler cannot generate code for something it can't see.
Templates aren't real code. The types are missing! They're just a template for real code, and since some of the types are missing they can't be compiled separately. Therefore they don't belong in cpp files.
Topic archived. No new replies allowed.