I use templates to implement a CRTP template. With the code below, I get linker errors (for all methods that are defined in the CPConnectionBase base class) as follows:
error LNK2001: unresolved external character "public: void __thiscall CPConnectionBase :: start (void)" (? start @? $ CPConnectionBase @VTNCPConnection @@@@ QAEXXZ)
I think the solution here is to explicitly create a template. And indeed, I can create my code when I add
#include "TNCPConnection.h" template class CPConnectionBase<TNCPConnection>;
to the CPConnectionBase.cpp file. This, of course, is the wrong place, because I do not want to include the header of all possible derived classes in the source code of the base class (I could use the base class in another project with other derived classes).
So, my goal is to create an instance of the template in the source file of the derived class (TNCPConnection.h or TNCPConnection.cpp), but I could not find a solution. Adding
template class CPConnectionBase<TNCPConnection>;
to the TNCPConnection.cpp file does not solve my problems with the linker and adds
template<> class CPConnectionBase<TNCPConnection>;
to the TNCPConnection.cpp file gives me a compile-time error:
bug C2908: explicit specialization; "CPConnectionBase" has already been created
How can I get rid of linker errors without making the base class implementation dependent on the derived class header files?
Here is the skeleton of my code:
CPConnectionBase.h
template <class Derived> class CPConnectionBase : public boost::enable_shared_from_this<Derived> { public: void start(); };
CPConnectionBase.cpp
#include "stdafx.h" #include "CPConnectionBase.h" template<class Derived> void CPConnectionBase<Derived>::start() { ... }
TNCPConnection.h
#include "CPConnectionBase.h" class TNCPConnection : public CPConnectionBase<TNCPConnection> { public: void foo(void); };
TNCPConnection.cpp
#include "stdafx.h" #include "TNCPConnection.h" void TNCPConnection::foo(void) { ... }