Problem
I am currently getting an undefined reference error for member functions defined outside a header file for a class called Vec2D. How can I resolve this error?
CMakeFiles\Scavens.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x20): undefined reference to `Vec2D<int>::Vec2D(int, int)'
CMakeFiles\Scavens.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x33): undefined reference to `operator<<(std::ostream&, Vec2D<int> const&)'
CMakeFiles\Scavens.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x59): undefined reference to `Vec2D<int>::Vec2D(int, int)'
CMakeFiles\Scavens.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x69): undefined reference to `Vec2D<int>::operator=(Vec2D<int> const&)'
CMakeFiles\Scavens.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x7c): undefined reference to `operator<<(std::ostream&, Vec2D<int> const&)'
CMakeFiles\Scavens.dir/objects.a(main.cpp.obj):main.cpp:(.text+0xa2): undefined reference to `Vec2D<int>::Vec2D(int, int)'
CMakeFiles\Scavens.dir/objects.a(main.cpp.obj):main.cpp:(.text+0xb2): undefined reference to `Vec2D<int>::operator+=(Vec2D<int> const&)'
CMakeFiles\Scavens.dir/objects.a(main.cpp.obj):main.cpp:(.text+0xc5): undefined reference to `operator<<(std::ostream&, Vec2D<int> const&)'
CMakeFiles\Scavens.dir/objects.a(main.cpp.obj):main.cpp:(.text+0xeb): undefined reference to `Vec2D<int>::Vec2D(int, int)'
CMakeFiles\Scavens.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x102): undefined reference to `Vec2D<int>::Vec2D(int, int)'
CMakeFiles\Scavens.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x112): undefined reference to `Vec2D<int>::operator+(Vec2D<int> const&)'
CMakeFiles\Scavens.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x121): undefined reference to `Vec2D<int>::operator=(Vec2D<int> const&)'
CMakeFiles\Scavens.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x134): undefined reference to `operator<<(std::ostream&, Vec2D<int> const&)'
collect2.exe: error: ld returned 1 exit status
mingw32-make[2]: *** [CMakeFiles\Scavens.dir\build.make:134: Scavens.exe] Error 1
mingw32-make[1]: *** [CMakeFiles\Makefile2:99: CMakeFiles/Scavens.dir/all] Error 2
mingw32-make: *** [Makefile:90: all] Error 2
What I have tried
I have currently tried nothing, because I don't why this error is occurring.Sources
Top level CMake file:
cmake_minimum_required(VERSION 3.20.5)
set(CMAKE_CXX_STANDARD 17)
add_definitions(-DUNICODE -D_UNICODE)
project(Scavens)
add_executable(${PROJECT_NAME} main.cpp src/Scavens.cpp src/Vector2D.cpp)
add_subdirectory(lib)
target_include_directories(${PROJECT_NAME} PRIVATE include)
target_link_libraries(${PROJECT_NAME} PRIVATE windowEngine)
File structure:
Root
|_ assets
|_ build
|_ lib
|_ include
|_ Vector2D.hpp
|_ src
|_ Vector2D.cpp
|_ main.cpp
|_CMakelists.txt
Header file:
#pragma once
#include <iostream>
template <typename T>
class Vec2D{
public:
Vec2D();
Vec2D(T t_X, T t_Y);
Vec2D(const Vec2D<T> &t_Vec2D);
Vec2D<T>& operator=(const Vec2D<T> &t_Vec2D);
Vec2D<T>& operator+(const Vec2D<T> &t_Vec2D);
Vec2D<T>& operator-(const Vec2D<T> &t_Vec2D);
Vec2D<T>& operator+=(const Vec2D<T> &t_Vec2D);
Vec2D<T>& operator-=(const Vec2D<T> &t_Vec2D);
friend std::ostream& operator<<(std::ostream &t_Output, const Vec2D<T> &t_Vec2D);
friend std::istream& operator>>(std::istream &t_Input, Vec2D<T> &t_Vec2D);
public:
T m_X,m_Y;
};
Source file:
#include "Vector2D.hpp"
template <typename T>
Vec2D<T>::Vec2D() : m_X(0),m_Y(0) {}
template <typename T>
Vec2D<T>::Vec2D(T t_X, T t_Y) : m_X(t_X), m_Y(t_Y) {}
template <typename T>
Vec2D<T>::Vec2D(const Vec2D<T> &t_Vec2D) : m_X(t_Vec2D.m_X), m_Y(t_Vec2D.m_Y) {}
template <typename T>
Vec2D<T>& Vec2D<T>::operator=(const Vec2D<T> &t_Vec2D)
{
m_X = t_Vec2D.m_X;
m_Y = t_Vec2D.m_Y;
return *this;
}
template <typename T>
Vec2D<T>& Vec2D<T>::operator+(const Vec2D<T> &t_Vec2D)
{
return *this += t_Vec2D;
}
template <typename T>
Vec2D<T>& Vec2D<T>::operator-(const Vec2D<T> &t_Vec2D)
{
return *this -= t_Vec2D;
}
template <typename T>
Vec2D<T>& Vec2D<T>::operator+=(const Vec2D<T> &t_Vec2D)
{
m_X += t_Vec2D.m_X;
m_Y += t_Vec2D.m_Y;
return *this;
}
template <typename T>
Vec2D<T>& Vec2D<T>::operator-=(const Vec2D<T> &t_Vec2D)
{
m_X -= t_Vec2D.m_X;
m_Y -= t_Vec2D.m_Y;
return *this;
}
template <typename T>
std::ostream& operator<<(std::ostream &t_Output, const Vec2D<T> &t_Vec2D)
{
t_Output << "( " << t_Vec2D.m_X << ", " << t_Vec2D.m_Y << " )";
return t_Output;
}
template <typename T>
std::istream& operator<<(std::istream &t_Input, Vec2D<T> &t_Vec2D)
{
t_Input >> t_Vec2D.m_X >> t_Vec2D.m_Y;
return t_Input;
}