defining template class functions in a .cpp file

hi

Visual studio wont allow me to initialise my function in my .cpp file because it has a template. As a result its asking me to create another template in my .cpp file (which seems ludacris, since when I do that it would seem as if i have 2 independent templates)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
	
template <class qXType_state>
class CStateMachine
{
private:
	
	//This pointer points to the "owner" of this instance
	qXType_state*               qmp_Owner;
	//the current state being used
	CStates<qXType_state>*      qmp_CurrentState;
	//a record of the last state used
	CStates<qXType_state>*      qmp_PreviousState;

public:
	
//set current state
	void SetCurrentState(CStates<qXType_state>* qp_st);

...
1
2
3
4
5
6
//.cpp file
//set current state
	void CStateMachine::SetCurrentState(CStates<qXType_state>* qp_st) 
	{
		qmp_CurrentState = qp_st;
	}
Template declarations and definitions need to be in the same non-implementation file. This is because of the C++ compilation model (compilation units compiled separately). Say you have some template function, F, declared in T.h and defined in T.cpp. Now, say you want to call F in Foo.cpp (which included T.h). When it comes time to compile Foo.cpp, it will need to see the actual implementation of F, but it won't be able to because the implementation of F is in T.cpp!

You can do one of the following:
(1) put the implementation of SetCurrentState in the .h file and scrap the .cpp file.
(1.1) put the implementation of SetCurrentState in some other file (call it a .tlt or whatever you want) and have your .h file #include it. This makes it so that your project follows the "declarations in header files and definitions in implementation files", rule. Make sure that you tell your IDE that your file is not an implementation file. i.e.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//.h
template <class qXType_state>
class CStateMachine
{
private:
	
	//This pointer points to the "owner" of this instance
	qXType_state*               qmp_Owner;
	//the current state being used
	CStates<qXType_state>*      qmp_CurrentState;
	//a record of the last state used
	CStates<qXType_state>*      qmp_PreviousState;

public:
	
//set current state
	void SetCurrentState(CStates<qXType_state>* qp_st);
};

#include "CStateMachine.tlt" 


1
2
3
4
5
//CStateMachine.tlt
void CStateMachine::SetCurrentState(CStates<qXType_state>* qp_st) 
{
	qmp_CurrentState = qp_st;
}

or

(2) Explicitly tell the compiler which template instantiations your program uses. The process is described here:

http://www.parashift.com/c++-faq-lite/templates.html#faq-35.13

and here:

http://www.parashift.com/c++-faq-lite/templates.html#faq-35.15

Number 1 is called the "inclusion model" and number 2 is called the "separation model".
Last edited on
thanks
Topic archived. No new replies allowed.