Undefined Reference to '...' in C++

Started by
5 comments, last by sjaakiejj 13 years, 4 months ago
hi,

I've been working on a Finite State Machine in C++, and it's been a while since I last worked in C++ (Have been using C and Java for the past 2 years or so). Obviously this leads to some issues that might sometimes be trivial to solve, but it's all a bit rusty for me.

So here's a problem I came across and can't manage to solve.

The problem relates to 4 files, StateMachine.h, StateMachine.cpp, SpawnEntity.h and SpawnEntity.cpp.

In StateMachine.h, I define a function called changeState, with templates to make it reusable. This looks as follows:

StateMachine.h
//Forward declare classesclass State<class character_type>;template <class character_type>class StateManager{public:  StateMachine(){}  void changeState(State<character_type>*);  ~StateMachine(){}};


StateMachine.cpp
#include "main.h" //holds all header filestemplate <class character_type>void StateManager<character_type>::changeState(State<character_type>* newState){ //Do something  }


SpawnEntity.h
//Forward Declareclass TestType;class SpawnEntity : public State<TestType>{public:  void execute(TestType*);};


SpawnEntity.cpp
#include "main.h" //Same main as beforevoid SpawnEntity::execute(TestType* owner){   FSM->changeState(State_NextState); //This is where the error occurs}


The State Class is an abstract class which is implemented by classes such as SpawnEntity and NextState, to ensure consistent methods. TestType is derived from a class called Entity, specifying a few methods which aren't really relevant to this problem.
The error is as follows:

SpawnEntity.cpp:(.text+0xe6): undefined reference to `StateManager<TestType>::changeState(State<TestType>*)'


Thanks in advance for your help.
Advertisement
Long story short, you can't put template definitions in a .cpp file and have the program link. Move the definitions to the header.
So the cpp file becomes

#include "main.h" //holds all header filesvoid StateManager<TestType>::changeState(State<character_type>* newState){   //Do something  }


Although this would mean I have to redo this class each time I want to use a different type with it, unless I'm understanding what you said in the wrong way.

Thanks for your swift response by the way.
No, I meant move the entire template definition, exactly like you had it before, into the header.
I must admit I feel embarrassed, but I'm not quite sure what you mean with moving the template definitions to the header.

Thanks for your help so far.
Move all your template functions into the header file. If you have a template class, the entire class must live within the header file. Like this:

StateMachine.h
//Forward declare classesclass State<class character_type>;template <class character_type>class StateManager{public:  StateMachine(){}  template <class character_type>  void changeState(State<character_type>* newState)  { //Do something  }  ~StateMachine(){}};


SpawnEntity.h
//Forward Declareclass TestType;class SpawnEntity : public State<TestType>{public:  void execute(TestType* owner)  {    FSM->changeState(State_NextState);  }};


NOTE: not tested, but hopefully you get the idea.
Ah right :D

Thanks for clearing it up for me. I'm still getting used to templates in C++, I used them a lot in Java (of course they aren't called templates there, but they're both generics) and find that they are incredibly useful. I kind of converted that to C++ templates, and it often brings up some problems (which I thought I solved by defining the template in the source file as well..)

This topic is closed to new replies.

Advertisement