Undefined Reference to User Defined Type

Hello!

I have built a LinkedList template class and am trying to test out its functions on a user defined type (another class called Animal in the example below).

When I instantiate a Linked List object with an int type, there are no issues. However, when I try to instantiate a Linked List object with my user defined "Animal" type, I receive the following error message:

[1/2] Building CXX object CMakeFiles/LinkedListcpp.dir/main.cpp.obj
[2/2] Linking CXX executable LinkedListcpp.exe
FAILED: LinkedListcpp.exe
C:\bin\mingw\bin/ld.exe: CMakeFiles/L/CLionProjects/LinkedListcpp/main.cpp:26: undefined reference to `LinkedList<Animal>::LinkedList(int)'
collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

Note the name of the project is LinkedListcpp.

Here is the LinkedList code in linked_list.cpp:

1
2
3
4
5
6
template<typename T> LinkedList<T>::LinkedList(int item) {
    this->first    = nullptr;
    this->last     = nullptr;
    this->size     = 0;
    this->itemSize = item;
}


Here is the declaration in linked_list.h:

LinkedList(int);

Here is what I am trying to do in main.cpp:

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

class Animal{
public:
    Animal(std::string str){
        this->name = str;
    }

    std::string getName(){
        return this->name;
    }

private:
    std::string name;
};

int main() {

    LinkedList<Animal>* AList = new LinkedList<Animal>(0);

    return 0;
}


Any suggestions or insight would be greatly appreciated.
Last edited on
You can't separate a class or function template into a header file and .cpp file.
The compiler needs to know the full definition of the class and all functions to instantiate a class from a template.

Move all templated code (like your LinkedList constructor) to the header file.

Also, why dynamically allocate your LinkedList object on line 20?
You can just do:
LinkedList<Animal> list(0);

this->itemSize = item;
'item' is a poor name for a variable meant to indicate the size of the list. Perhaps just make it also be 'itemSize' or 'size'.
Last edited on
Moving the constructor to the header file solved this compilation error. Thank you!

Should all the code be moved into the header file, and then the cpp file is no longer needed?

Or should all the code go into a cpp file and then header file is no longer needed?

I'm only asking because I'm trying to make my project look a bit more professional, and wanted to hear some opinions on what would look better.
All the template code should go into the header file. People are generally used to #include "header.h", not #include "file.cpp".
Remember that #includes are just directives that copy-paste code into other files.

Some people prefer to make their lives harder by still separating the template declarations artificially from their implementations via 'inl' files (the naming is arbitrary).
https://stackoverflow.com/a/17698469
So it would look something like:
header.h
1
2
3
4
5
6
7
template <typename T>
class LinkedList {
   LinkedList(int size);
   ...
};

#include "header-inl.h" 


header-inl.h
1
2
3
4
template<typename T> LinkedList<T>::LinkedList(int size)
{
   ...
}


main.cpp
1
2
3
#include "header.h"

...


But I have never understood the point of this (I'm being somewhat obtuse; I do sort of understand the reason. It's arguably nicer to be able to glance at all the declarations in a header file as a quick overview of the class rather than having to rely on IDE minimization toggles/documentation generation.)
Last edited on
Topic archived. No new replies allowed.