GiCo
GiCo

Reputation: 586

Force template instantiation in another header

I have a templated "collection" class. I don't wan't the code be recompiled in every source file. But this collection should be used with DataTypes (class SpecialDataMember : DataMember) not defined on definition of the the template class. This is why I can't force the instantiation in the template source file (throug moving the definitions to the source file and add template LinkCollection<DataMember>;), because the definitions of the template must be accessible in other source files ("SpecialDataMember.cpp").

Is it possible to make "SpecialDataMember.o" hold the code for LinkCollection<SpecialDataMember>. Every includer of SpecialDataMember.h should know I leave LinkCollection<SpecialDataMember> to the linker.

I see two options but I don't know if they work:

  1. Make two template headers (with header guard) one with the definitions one without.

SpecialDataMember.h

// ..
include "LinkCollection.h"
// ..

SpecialDataMember.cpp

// .. 
include "LinkCollectionImpl.h"
// .. 
include "SpecialDataMember.h"
// .. 
template LinkCollection<SpecialDataMember>;

All includers of "SpecialDataMember.h" will not know the definitions of the template so they will let the linker do his work.And the linker will find the instantiation of LinkCollection<SpecialDataMember> in SpecialDataMember.o. Is that correct? But I would have to maintain two header Files. Is there a better way to gain this effect?

  1. Use template derived classes

If I create a special class SpecialDataMemberLinkCollection : LinkCollection<SpecialDataMemberLink> in the "SpecialDataMember" header and source file, I could reference this special class instead and so the compiler knows there is an instantiation of that class and the base class template and leaves the work to the linker. Will this work as expect?

Upvotes: 1

Views: 425

Answers (1)

Jonathan Wakely
Jonathan Wakely

Reputation: 171263

Is it possible to make "SpecialDataMember.o" hold the code for LinkCollection<SpecialDataMember>. Every includer of SpecialDataMember.h should know I leave LinkCollection<SpecialDataMember> to the linker.

Simple, just put:

extern template class LinkCollection<SpecialDataMember>;

in the header, which tells the compiler not to instantiate that template and leave it to another file.

Then in one SpecialDataMember.cpp file provide that instantiation:

template class LinkCollection<SpecialDataMember>;

Upvotes: 3

Related Questions