Click to See Complete Forum and Search --> : Massive Headache with Templates...


Metro_Mystery
May 13th, 2008, 01:07 AM
I've got a really annoying unresolved symbol linker error in code I've written that uses a templatized State Design Pattern.

It starts like this...



#ifndef __ISTATE_H__
#define __ISTATE_H__

template <typename T>
class IState
{
public:
virtual void Enter(T* ) = 0;
virtual void Execute(T* ) = 0;
virtual void Exit(T* ) = 0;
};

#endif

#ifndef __ENGINE_STATE_H__
#define __ENGINE_STATE_H__

#include "State.h"

template <typename T>
class IEngineState: public IState<T>
{
public:
virtual bool KeyboardEvent(irr::SEvent& , T* ) = 0;
virtual bool MouseEvent(irr::SEvent& , T* ) = 0;
virtual bool MouseGUIEvent(irr::SEvent& , T* ) = 0;
};

#endif

#ifndef __STATE_MACHINE_H__
#define __STATE_MACHINE_H__

#include "State.h"

template <typename T>
class StateMachine
{
public:

StateMachine(T* pOwner);
~StateMachine();

void Update();

IState<T>* GetCurrentState() const;
IState<T>* GetGlobalState() const;
IState<T>* GetPreviousState() const;

bool IsInState(IState<T>* s) const;

void ChangeState(IState<T>* pNewState);
void RevertToPreviousState();

void SetCurrentState(IState<T>* s);
void SetPreviousState(IState<T>* s);
void SetGlobalState(IState<T>* s);

private:
T* m_pOwner;

IState<T>* m_pCurrentState;
IState<T>* m_pPreviousState;
IState<T>* m_pGlobalState;
};

#endif



#ifndef __GAME_ENGINE_H__
#define __GAME_ENGINE_H__

class CGameEngine
{
public:

StateMachine<CGameEngine>* GetFSM();

private:
StateMachine<CGameEngine>* m_pStateMachine;
};

#endif


The offending code occurs in the game constructor- when I create the StateMachine to hold a reference to the owning GameEngine object...


CGameEngine::CGameEngine() :
m_pStateMachine(NULL), m_pIrrDev(NULL), m_pIrrSceneMan(NULL), m_pIrrGuiEnv(NULL)
{
m_pStateMachine = new StateMachine<CGameEngine>(this);
}


1>GameEngine.obj : error LNK2019: unresolved external symbol "public: __thiscall StateMachine<class CGameEngine>::StateMachine<class CGameEngine>(class CGameEngine *)" referenced in function "public: __thiscall CGameEngine::CGameEngine(void)"

It's saying the constructor is undefined in the StateMachine class... but I've declared it like so...


template <typename T>
StateMachine<T>::StateMachine(T* pOwner):
m_pOwner(pOwner), m_pCurrentState(NULL), m_pPreviousState(NULL), m_pGlobalState(NULL)
{

}


I can't figure it out and I've been looking at it all day... Any help is REALLY appreciated.

Thanks.

souldog
May 13th, 2008, 01:42 AM
where did you implement this constructor? Template code needs to be implemented in the header file for most, maybe all, compilers.

Metro_Mystery
May 13th, 2008, 02:31 AM
Souldog- you are a champion!

Something as simple as putting template files in a source file causes linker problems. I've scratched my head all day trying to figure out what could possibly have caused this problem

Thanks again buddy!