Template code organization

D

dizzy

Hello

When working with template heavy code one will have to face the
inherent "problems" of the inclusion model because of the requirement
to provide the definition of the template at every place where it is
used. This means problems with include separation and problems with
code duplication (the later depends largely on your toolchain but
unless I am missing out on a modern standard compliant and free as in
free beer compiler that does remove template code instantiation
duplicates then this is a problem I have to deal with).

1. Include separation

In order to enable implicit template instantiations we must provide
the definition of the template code at the place of instantiation.
This is usually done by having the template code definition either in
the same header as the template interface or included by it. This
means when you have your own header that uses some template class it
will include the template class header which has the member functions
definitions which require their own includes thus bringing include
dependencies that were of the template code implementation alone.

A solution may be to separate the code from the template definitions
that needs its own includes into some non template code for which we
provide only declarations and the template definitions will call upon
them and have them defined in a separate cpp file that will have those
includes.

Or another solution would be a general approach to template code to
have only the declarations (of functions, for class/structs we put
their definition but not with the function members definitions) in the
header that describes the interface of the template code, then have
the definitions in a say .tcc file. Code that wants implicit
instantiation for those templates can include the tcc file directly
(so this needs an include guard itself similar to normal header files)
or can include only the header file with the declarations. Then in the
cpp file of the template code user it can include the .tcc file and
instantiate the templates using explicit instantiation.

Do you have another solution that you know is being used in practice
and seems to work well for medium/large projects?

2. Template instantiation code duplication

For some reason, my toolchain (g++ 4.x, ld 2.18) seems to create huge
executables in size for template heavy programs. This I think is
because the linker does not remove the duplicate code definitions (it
may remove just the duplicate symbols leaving the code to use space).
So if I use std::string in 100 translation units I will get 100
definitions of std::string constructor.

For this problem I can't come up with a reasonable solution, any idea?

PS: g++'s -frepo argument and functionality does not really help; the
overall project compilation time increases and while -frepo may
eliminate some double instancing of some code it certainly doesn't
eliminate multiple instances of very commonly used code (like
std::string)
 
T

Thelma Roslyn Lubkin

: Hello

: When working with template heavy code one will have to face the
: inherent "problems" of the inclusion model because of the requirement
: to provide the definition of the template at every place where it is
: used. This means problems with include separation and problems with
: code duplication (the later depends largely on your toolchain but
: unless I am missing out on a modern standard compliant and free as in
: free beer compiler that does remove template code instantiation
: duplicates then this is a problem I have to deal with).

Are you using the preprocessor's #ifdef and #ifndef keywords
to reduce the amount of duplication?
--thelma
: --
: Dizzy
 
M

mqrk

When working with template heavy code one will have to face the
inherent "problems" of the inclusion model because of the requirement
to provide the definition of the template at every place where it is
used.

I don't know that there is any way around this with g++ and ld.
2. Template instantiation code duplication

For some reason, my toolchain (g++ 4.x, ld 2.18) seems to create huge
executables in size for template heavy programs. This I think is
because the linker does not remove the duplicate code definitions (it
may remove just the duplicate symbols leaving the code to use space).
So if I use std::string in 100 translation units I will get 100
definitions of std::string constructor.

I find that surprising, but that may well be. Have you tried using
explicit template instantiation? Here's my (possibly mistaken)
understanding of how it works:

//SomeHeader.h
template <class T>
class MyClass
{
public:
void f() {}
};

extern template class A< Widget >; //A< Widget > is used a lot

//MyTemplate.cpp
#include "SomeHeader.h"
template class A< Widget >;

Now, when a source file includes SomeHeader.h, the compiler won't
instantiate A< Widget >, but it should link properly with MyTemplate.o

Perhaps you could even just have a header file for commonly used
template instances (I have not tested this)

//MyExternTemplates.h
#include <string>
#include "IWidget.h"
#include "IGadget.h"

extern template class Widget< int >;
extern template class Widget< float >;
extern template class Widget< char >;
// ... etc.

//MyExternTemplates.cpp
#include "MyExternTemplates.h"
template class Widget< int >;
template class Widget< float >;
// ... etc.

If nothing else, this should cut down on compile-time.

Regards,
Mark McKenna
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top