Jump to content
  • Advertisement
Sign in to follow this  
directNoob

Class Template throws "unresolved externals"

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

Hi. I made a class template for a scene, called
template< typename T >
class CScene
{
. . .
} ;

Then, in Main.h, I declared a pointer to this class template, like this:
CScene< ISolarSystem > *pMilkyScene ;

Then in Main.cpp, I give memory to the pointer to the class template:
pMilky = new CMilkyWay() ;
pMilkyScene = new CScene< ISolarSystem > ;

pMilky is a pointer of the type ISolarSystem and CMilkyWay is a class derived from ISolarSystem. Then, after the preceeding definitions, I assign the pMilky to the class template pointer, like this:
pMilkyScene->Initialize( "Solar System" ) ;
pMilkyScene->AppendObject( pMilky ) ;

This seems not to work, because I get the following:
Quote:
1>Main.obj : error LNK2019: unresolved external symbol "public: bool __thiscall CScene<class ISolarSystem>::AppendObject(class ISolarSystem * &)" (?AppendObject@?$CScene@VISolarSystem@@@@QAE_NAAPAVISolarSystem@@@Z) referenced in function "void __cdecl SpecialKeys(int,int,int)" (?SpecialKeys@@YAXHHH@Z) 1>Main.obj : error LNK2019: unresolved external symbol "public: bool __thiscall CScene<class ISolarSystem>::Initialize(char *)" (?Initialize@?$CScene@VISolarSystem@@@@QAE_NPAD@Z) referenced in function "void __cdecl SpecialKeys(int,int,int)" (?SpecialKeys@@YAXHHH@Z) 1>Main.obj : error LNK2019: unresolved external symbol "public: bool __thiscall CScene<class ISolarSystem>::Release(void)" (?Release@?$CScene@VISolarSystem@@@@QAE_NXZ) referenced in function "public: __thiscall CScene<class ISolarSystem>::~CScene<class ISolarSystem>(void)" (??1?$CScene@VISolarSystem@@@@QAE@XZ) 1>D:\D_Programming\D_P_FH\Semester2\Cg\Pr01\Praktikum01\Debug\Praktikum01.exe : fatal error LNK1120: 3 unresolved externals
Those functions are defined within CScene.cpp like :
...

template< typename T >
bool CScene< T >::AppendObject( T* &rObj )
{
   m_pSceneObjects->push_back( &rObj ) ;
   return true ;
}
...


Has anybody any idea what could be wrong??? Grateful Alex

Share this post


Link to post
Share on other sites
Advertisement
Template implementation needs to go in the template header (it can go underneath the class, it doesn't have to be inlined).

This is due to the way compilers need to see the template to generate the code. In future, more compilers may allow the "export" keyword, which will allow you to put template code in a source file.

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
In future, more compilers may allow the "export" keyword, which will allow you to put template code in a source file.


That's unlikely. The one single vendor (EDG) that produced a compiler with full support for the export keyword says it doesn't work the way people expect, it's difficult or impossible to get absolutely correct, and does not lend any real advantage. There has been a lot of talk on the standards committee about removing that feature from the language entirely.

The accepted solution is to either (1) put the entire template definition in a header file and rely on precompiled headers if build speed is a problem, or (2) place non-inline template definitions in a separate header file than is the template declaration, and include both headers in a .cpp file and explicitly instantiate the template. The latter solution is less flexible but more desireable when a limited deomain of template arguments is expected.

--smw

Share this post


Link to post
Share on other sites
Hi.

Thanks!

But there is even a third method, but is similar to the second described by
Bregma .

I put the declaration of the class in the header file CScene.h.
The definition, I put, as expaced, into a .cpp file, namely CScene.cpp.
In main.h then, I included the CScene.cpp file instead of CScene.h.
This works. I have forgotten about the thing with the cpp file...

I think this method is quite comfortable or do you have any other opinion?!


Thanks
Alex

Share this post


Link to post
Share on other sites
Quote:
Original post by directNoob
Hi.

Thanks!

But there is even a third method, but is similar to the second described by
Bregma .

I put the declaration of the class in the header file CScene.h.
The definition, I put, as expaced, into a .cpp file, namely CScene.cpp.
In main.h then, I included the CScene.cpp file instead of CScene.h.
This works. I have forgotten about the thing with the cpp file...

I think this method is quite comfortable or do you have any other opinion?!


Thanks
Alex


Well, an IDE will probably put the source file in the build list, then waste some time dealing with it when there is no non-template code in it. But I have seen the same idea done differently, like having template_foo.h and template_foo_impl.h and #including the second in the first.

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!