Templates in cpp files

Started by
1 comment, last by VanillaSnake21 13 years, 11 months ago
Hi again, I'm a little confused about templates and their implementations. I've read that it's a good idea to put the definitions in the header file, but that makes it so messy. Is there a way to put the implementations in their own cpp file? I wrote a small test program, but I got an error: TemplateTest.h

#ifndef TEMPLATE_TEST_H
#define TEMPLATE_TEST_H

template<typename T>
class TemplateTest
{
public:
	TemplateTest()
	{
	}

	void setData(const T& data)
	{
		mData = data;
	}
	T getData() const
	{
		return mData;
	}

private:
	T mData;
};

#endif


TemplateTest.cpp:

#include "TemplateTest.h"

template<typename T>
TemplateTest<T>::TemplateTest()
{
}

template<typename T>
void TemplateTest<T>::setData(const T& data)
{
	mData = data;
}

template<typename T>
T TemplateTest<T>::getData() const
{
	return mData;
}


Main.cpp

#include <iostream>
#include "TemplateTest.h"

using namespace std;

int main()
{
	TemplateTest<int> intTest;

	intTest.setData(10);

	cout << intTest.getData();
}


When I compile it with the definitions in the TemplateTest header file, it works fine. If I comment out those definitions and use the cpp file, I get these errors:

error LNK2019: unresolved external symbol "public: int __thiscall TemplateTest<int>::getData(void)const " (?getData@?$TemplateTest@H@@QBEHXZ) referenced in function _main
1>Main.obj : error LNK2019: unresolved external symbol "public: void __thiscall TemplateTest<int>::setData(int const &)" (?setData@?$TemplateTest@H@@QAEXABH@Z) referenced in function _main
1>Main.obj : error LNK2019: unresolved external symbol "public: __thiscall TemplateTest<int>::TemplateTest<int>(void)" (??0?$TemplateTest@H@@QAE@XZ) referenced in function _main
1>TemplateTest.exe : fatal error LNK1120: 3 unresolved externals
So, two questions: 1. Why do I get these errors when using the cpp file definitions? 2. Is there a way to separate the class/struct/whatever in the header file from the implementation into separate files? Thanks Edit - also, what would be a good way to initialize mData to a default value? I'm not sure how to do this because I don't know the type of mData when writing the constructor (obviously).
Advertisement
So when the compiler sees a new type used with your template, like your TemplateTest<int> in Main.cpp, its going to need to generate the code for it. You've supplied the header file, but this isn't enough. That just includes the function declarations. It needs the functions definitions from your cpp file to generate everything. Thus, you either need to set up all the different instances of TemplateTest<> in TemplateTest.cpp so they get generated or include TemplateTest.cpp at the end of TemplateTest.h and take out the include of the header at the top of the cpp file. The latter is probably the best route since you may not know what types will be instantiated.
Basically because the templates aren't really classes the linker doesn't see the definition from the header, if its in a separate cpp file. Check this out, it's a similar question to yours.

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

This topic is closed to new replies.

Advertisement