I am trying to implement an inheritance chain whereby methods declared on the base type return the derived type by value. For example, I have a base class Base
with a method func()
. On a derived class Derived
, I want func()
to return an instance of Derived
by value.
To do this, I am trying to use "static polymorphism": the base class takes the derived class via a template parameter, and then makes the method return the template type. Here is my header file:
#pragma once
template<typename Derived>
class Base {
public:
Derived func() const;
};
class DerivedA : public Base<DerivedA> {
public:
DerivedA() : Base() {}
DerivedA(const Base<DerivedA>& other) : Base(other) {}
};
So far so good. I define the function in a cpp file:
#include <iostream>
template<typename Derived>
Derived Base<Derived>::func() const {
std::cout << "Calling func" << std::endl;
return Derived(*this);
}
And then I call it in a main function:
#include "demo.h"
int main() {
DerivedA a;
a.func();
return 0;
}
Unfortunately, compiling this code results in the following linker error.
main.cpp.o: In function `main': main.cpp:6: undefined reference to `Base<DerivedA>::func() const'
collect2: error: ld returned 1 exit status
Here is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.7)
project(demo)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp demo.cpp demo.h)
add_executable(demo ${SOURCE_FILES})
Oddly, if I move the definition into the header file, the code compiles without the linker error.
How do I properly define the function (ideally in a cpp file) and make the linker error go away?