Linker 2019 error unresolved external symbol

I am pretty sure I have something wrong with how I am using my templates like syntax. I am making a program that works with an array-based Queue. I might have had this issue before but I can't remember what it was I fixed.
I just put everything in a namespace because it wasn't before, but now it's back to this linker error. The first one is either from my default or parameterized or copy constructor, and then it goes down from there. I only put the first 3 functions. Actually I am also going to paste this into replit to make sure it's not just my compiler...
I also noticed I only have errors with my public functions.


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
#ifndef ARRAY_QUEUE_H
#define ARRAY_QUEUE_H

namespace cs_array {

    template<class ItemType>
    class ArrayQueue
    {
    public:
        ArrayQueue();
        ArrayQueue(const ArrayQueue& right);
        ArrayQueue operator =(const ArrayQueue<ItemType>& right);
        ~ArrayQueue();
        bool isEmpty() const;
        void enqueue(const ItemType& newEntry);
        void dequeue();
        ItemType peekFront() const;
        void print() const;
        int getSize();
    private:
        static const int DEFAULT_CAPACITY = 1;
        ItemType* items;
        int front;
        int back;
        int numItems;
        int capacity;
        void resize(int newCapacity);
    };
}
#endif 


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
#include <iostream>
#include "ArrayQueue.h"

namespace cs_array {

    template<class ItemType>
    ArrayQueue<ItemType>::ArrayQueue() {
        front = 0;
        back = DEFAULT_CAPACITY - 1;
        numItems = 0;
        capacity = DEFAULT_CAPACITY;
        items = new ItemType[DEFAULT_CAPACITY];
    }

    template<class ItemType>
    ArrayQueue<ItemType>::ArrayQueue(const ArrayQueue& right)
    {
        numItems = right.numItems;
        front = right.front;
        back = right.back;
        capacity = right.capacity;
        items = new ItemType[capacity];
        for (int i = 0; i < numItems; i++)
        {
            items[i] = right.items[i];
        }

    }

    template<class ItemType>
    ArrayQueue<ItemType> ArrayQueue<ItemType>::operator=(const ArrayQueue<ItemType>& right)
    {
        if (this != &right)
        {
            delete[] items;
            numItems = right.numItems;
            capacity = right.capacity;

            items = new ItemType[capacity];
            for (int i = 0; i < numItems; i++)
            {
                items[i] = right.items[i];
            }
        }
        return *this;
    }
#endif 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "ArrayQueue.h"
#include <iostream>
#include <string>
#include <array>

using namespace cs_array;
using namespace std;

int main()
{
    ArrayQueue<int> ArrayTest;
    for (int i = 0; i < 5; i++) 
    {
        ArrayTest.enqueue(1);
    }
    ArrayTest.enqueue(3);
    ArrayTest.enqueue(2);
    ArrayTest.enqueue(1);

    ArrayTest.print();
    cout << "The capacity is " << ArrayTest.getSize();

	return 0;
}
Last edited on
Function templates and member functions of class templates need to be defined in the same translation unit where they get used. Therefore you normally see them defined in the header.
Wait so I declare and define my templates all in arrayqueue.h ? I understand the format/parameters need to match for templates too, so I am not sure I need another "<ItemType>" when I wrote "operator=(const ArrayQueue<ItemType>& right)", but it seemed to accept it.
Wait so I declare and define my templates all in arrayqueue.h ?
Yes. The compiler can't generate the code for the template until it knows the template parameter class. That means it needs to know the declaration and the definition whenever you use the template.
Right, so in a header file the template should be in the right format, and then the implement file should also match. I guess I should mention the files shown are header, implement, and main, from top to bottom. I am not seeing where I messed up.
You're messing up by having an "implementation" (.cpp) file for a class template. Move everything from your ArrayQueue.cpp into the bottom of ArrayQueue.h. Delete ArrayQueue.cpp.

And I assume this is just a copy-paste error, but you are missing the } and have an extraneous #endif in your second file excerpt.
Last edited on
Ya I am pretty confused now, because I looked at my past template assignments and I did all of this. Including a .cpp into my header (I know I should not do this now) I then defined the templates in the .cpp. So I don't even know what I did to get the previous ones to compile.
Ok I got it to run, my bad I got confused and forgot I usually kick the .cpp out of the project, and then keep the #include in the header.
Including a .cpp into my header (I know I should not do this now) I then defined the templates in the .cpp
That's actually one of the few times when people will #include a .cpp file. But personally I don't see the point; it's just extra time/effort to split it when it eventually gets recombined anyway.
Last edited on
Topic archived. No new replies allowed.