2
votes

How can I get the template definition into a seperate header files?

My code compiles when it is included in a single main.cpp.

maip.cpp

#include <windows.h>
#include <tchar.h>

template<class T1, class T2>
class Base {
public:
    virtual ~Base() {}
    virtual T1 f1();
    virtual T2 f2();
};

template<class T1, class T2>
T1 Base<T1, T2>::f1() {return T1();}
template<class T1, class T2>
T2 Base<T1, T2>::f2() {return T2();}

class Derived : public Base<int, int> {
public:
    virtual ~Derived() {}
};

int _tmain(int argc, _TCHAR* argv[])
{
    int i;
    Derived d;
    i = d.f1();
    return 0;
}

However, when I break it up I get unresolved external symbols:

main.cpp

#include <windows.h>
#include <tchar.h>

#include "Base.h"
#include "Derived.h"

int _tmain(int argc, _TCHAR* argv[])
{
    int i;
    Derived d;
    i = d.f1();
    return 0;
}

Base.h

#pragma once

template<class T1, class T2>
class Base {
public:
    Base();
    virtual ~Base() {}
    virtual T1 f1();
    virtual T2 f2();
};

template<class T1, class T2>
T1 Base<T1, T2>::f1() {return T1();}
template<class T1, class T2>
T2 Base<T1, T2>::f2() {return T2();}

Derived.h

#pragma once

class Derived : public Base<int, int> {
public:
    virtual ~Derived() {}
};

This results in:

Error 1 error LNK2019: unresolved external symbol "public: __thiscall Base::Base(void)" (??0?$Base@HH@@QAE@XZ) referenced in function "public: __thiscall Derived::Derived(void)" (??0Derived@@QAE@XZ)

1
minor point: Derived.h should include Base.h since it inherits from Base, it's awkward to ask clients to include the files in a precise order, therefore each header should be self-sufficient (ie should compile without anything included before it). - Matthieu M.

1 Answers

5
votes

You didn't provide an implementation for Base's constructor. Try adding

template<class T1, class T2>
Base<T1, T2>::Base () { }

Alternatively, you can remove its declaration from your second code snippet. (It is also not present in your first code example).

Your linker basically says that Derived::Derived () tries to call Base::Base (), which you explicitly declared, but he can't locate an implementation for it.