templates and linker error

Started by
3 comments, last by Rhiakath 13 years, 9 months ago
Ok, here's ANOTHER template question!
(I told you, I don't get along with templates)

Here's my code:

#ifndef INSTANCELOCATOR_INCLUDED#define INSTANCELOCATOR_INCLUDED#include <vector>namespace Utils	{	template <typename T> class TInstanceLocator		{		private:			static std::vector <T*>			Instances;		public:			TInstanceLocator ( void )				{				Instances.push_back(static_cast <T*> ( this ));				printf("Added instance of %s (%X)\r\n",typeid(T).name(), this);				}			~TInstanceLocator ( void )				{				}			T GetInstance(unsigned In_Index)				{				return Instances[In_Index];				}		};	}#endif


I get an unresolved external symbol whenever i insert the push_back line. What's up with this?

Basically, this will be something like a singleton template class, but with multiple objects. Just to be able to acess all of the instantiated objects of a certain type :D
Thanks,

[Edited by - ApochPiQ on July 19, 2010 1:18:51 PM]
Advertisement
It would help if you posted the actual error message.

However, make sure you've declared that Instances vector in your cpp file.

Also, looking at the code it would appear the GetInstance() function should return a "T*" instead of a "T".

Also be very careful with code like this, as the initialization order of static class members isn't well defined. This means if a global object inherits from TInstanceLocator it may (or may not) find that the Instances vector isn't initialized.

There may be other issues I've not spotted.
#ifndef INSTANCELOCATOR_INCLUDED#define INSTANCELOCATOR_INCLUDED#include "Array.h"namespace Utils	{	template <typename T> class TInstanceLocator		{		private:			static Utils::CArray <typename T*>	Instances;					public:			TInstanceLocator ( void )				{				Instances.Push(static_cast <typename T*> ( this ));				printf("Added instance of %s (%X)\r\n",typeid(T).name(), this);				}			~TInstanceLocator ( void )				{				for (unsigned cont=0;cont<Instances.Size();++cont)					{					if (Instances[cont]==static_cast <T*> ( this ))						{						Instances.DeleteAt(cont);						printf("Deleted instance of %s (%X)\r\n",typeid(T).name(), this);						return;						}					}				throw std::exception ("InstanceLocator destructor called, but unable to erase");				}			T* GetInstance(unsigned In_Index)				{				return Instances[In_Index];				}		};	}#endif


Array <> is just something like a stl vector. It just works. It's a template.

the error message is
error LNK2001: unresolved external symbol "private: static class Utils::CArray<class Obj *> Utils::TInstanceLocator<class Obj>::Instances" (?Instances@?$TInstanceLocator@VObj@@@Utils@@0V?$CArray@PAVObj@@@2@A)
When you have a static member variable, the part inside the class is only the declaration for the variable. You still need to create a definition for the the variable. This is true for both template and non-template classes. For a template class the definition looks like:
template<typename T> std::vector <T*> TInstanceLocator<T>::Instances;

For a template class this usually goes in the header that contains the definition of the template class after the class definition in the same namespace.
Templates are too confusing.... :S

But hey, I guess it worked. Gonna test it now..

This topic is closed to new replies.

Advertisement