Jump to content
  • Advertisement
Sign in to follow this  
Rhiakath

templates and linker error

This topic is 2866 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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]

Share this post


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

Share this post


Link to post
Share on other sites

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

Share this post


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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!