I have a simple cmake project where I'm implementing a virtual function f() outside the header file base.h, in base.cpp. Here's base.h
#include <iostream>
template<typename T>
class Base {
public:
virtual void f(const T& t) const = 0;
};
template<typename T>
class Derived : public Base<T> {
public:
void f(const T& t) const final;
};
and base.cpp
#include "base.h"
template <typename T>
void Derived<T>::f(const T& t) const {
std::cout << t << std::endl;
}
and run via main.cpp
#include <iostream>
#include "base.h"
int main() {
Derived<double> e;
e.f(2);
}
My CMakeLists.txt reads:
cmake_minimum_required(VERSION 3.21)
project(MyProject)
set(CMAKE_CXX_STANDARD 17)
add_executable(MyProject main.cpp base.cpp)
However I get the following error message
Undefined symbols for architecture arm64:
"Derived<double>::f(double const&) const", referenced from:
_main in main.cpp.o
vtable for Derived<double> in main.cpp.o
ld: symbol(s) not found for architecture arm64
The code compiles successfully if I instead implement the virtual function in base.hpp in-place, instead of externally in base.cpp. It also compiles if I remove the template <typename T> specification for the abstract Base class. What am I missing here, and how do I write the virtual function's implementation in a separate file?