Sign in to follow this  
Aiwendil

Templates in cpp files

Recommended Posts

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).

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this