Jump to content
  • Advertisement
Sign in to follow this  
TheMightyDude

Help with Templates

This topic is 3774 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

Hello All I have used templates all within a header file for a while now, but when I try and separate the code into .h and .cpp files it breaks :( It all worked fine when all the hash class functions were all in the header file within the class itself. I really need to have this in separate header and source files, due to I plan to put this in a library with other classes, and if it all has to be in the header file then it’s not worth having the library. Anyone know how to resolve this, I have looked for the last few hours, looking at example code and trying how they did it, but it still fails to compile :( What am I doing wrong ? Oh btw I am using Visual Studio 2003 if that helps.
// Error:
storage.obj : error LNK2019: unresolved external symbol "public: void __thiscall HashTable<int,class Player>::Initialize(int)" 
(?Initialize@?$HashTable@HVPlayer@@@@QAEXH@Z) referenced in function "public: __thiscall Storage::Storage(void)" (??0Storage@@QAE@XZ)


I have removed the bulk of the code or the post would of been very long. Hash Header File
// hash.h
template<typename KeyType, typename DataType> class HashTable
{
public:
    ...
    void Initialize(int p_size);
    ...
};


Hash Source File
// hash.cpp

#include "hash.h"

template<typename KeyType, typename DataType>
void HashTable<KeyType, DataType>::Initialize(int p_size)
{
    ...
}


Storage Header File
// storage.h
class Storage
{
public:
    HashTable<int, class Player> playerlist;
    HashEntry<int, class Player>* player;

    Storage();
    ...
};


Storage Source File
// storage.cpp

#include "hash.h"
#include "storage.h"

Storage::Storage()
{
	playerlist.Initialize(MAX_PLAYER_CELL);

}


Thanks in advance Paul Kirby

Share this post


Link to post
Share on other sites
Advertisement
Unless your compiler supports the 'export' keyword (which most don't) you need to put templates in the header file itself, or somehow include the template 'source' file into the header, or explicitly instantiate the templates.

Some people will make a file to put the template implementation into and #include it into the template header towards the file. These files usually get a different extension, for example '.tcc'.

I just put the template implementation code into the header file.

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
Unless your compiler supports the 'export' keyword (which most don't) you need to put templates in the header file itself, or somehow include the template 'source' file into the header, or explicitly instantiate the templates.

Some people will make a file to put the template implementation into and #include it into the template header towards the file. These files usually get a different extension, for example '.tcc'.

I just put the template implementation code into the header file.


Thanks for the very fast reply :)

Well I have created a file called "templateinstantiations.cpp" with the following in it.


// templateinstantiations.cpp
#include "hash.cpp"

#include "item.h"
#include "player.h"
#include "ship.h"

template class HashTable<int, class Player>; // explicit instantiation
template class HashTable<int, class Item>; // explicit instantiation
template class HashTable<int, class Ship>; // explicit instantiation



This fixed the errors that I was getting, however how would I put this in a library?

This file includes "hash.cpp" and when using a library file I wouldn't have access to "hash.cpp" only the header files.

And I can't put the 3 template class lines in hash.h or hash.cpp due to it doesn't know about the Player, Item or Ship Classes, which it shouldn't need to know about.

Thanks in advance
Paul Kirby

Share this post


Link to post
Share on other sites
Quote:
Original post by TheMightyDude
This fixed the errors that I was getting, however how would I put this in a library?

Basically, you wouldn't.

That's why the STL (or if anyone are pedantic enough to make a fuss about it, the STL-derived parts of the C++ Standard Library) is basically a bunch of header files.
There's no library for std::vector or std::for_each. They reside in header files because they're templates.

There's no good way around it.
If you expose a template, the entire template definition has to be visible in the same compilation unit. So you can't hide it away in a .cpp file, and supply it as a library.

Share this post


Link to post
Share on other sites
Move the template function definitions back into the header file, and get rid of your explicit instantiations. And never #include a .cpp file.

Have a read:
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12

Share this post


Link to post
Share on other sites
Thanks for all the replies...

I had a bad feeling that it would be better off all in the header file :(

I guess the next best thing is to put these header files in their own folder and include it when needed.

Thanks
Paul Kirby

Share this post


Link to post
Share on other sites
Quote:
Original post by TheMightyDude
how would I put this in a library?

Templates are only compiled once they're instantiated and used elsewhere, this is because the compiler needs to first know what the template parameters are going to be - so it wouldn't make sense to be able to compile a templated class/function into a library.

Share this post


Link to post
Share on other sites
It's possible to separate the class definition and the implementations, but they still have to be in the same file. This can be handy for readability:


template <class Foo>
class Bar
{
public:

Bar();
void Qux();
// other stuff
};

template <class Foo>
Bar<Foo>::Bar()
{

}

template <class Foo>
void Bar<Foo>::Qux()
{

}

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!