lytenyn
lytenyn

Reputation: 819

Compile header-only template library into a shared library?

We are in the process of designing a new C++ library and decided to go with a template-based approach along with some specific partial template specialisations for corner cases. In particular, this will be a header-only template library.

Now, there is some concern that this will lead to a lot of code duplication in the binaries, since this template 'library' will be compiled into any other shared library or executable that uses it (arguably only those parts that are used). I still think that this is not a problem (in particular, the compiler might even inline things which it could not across shared library boundaries).

However, since we know the finite set of types this is going to be used for, is there a way to compile this header into a library, and provide a different header with only the declarations and nothing else? Note that the library must contain not only the generic implementations but also the partial specialisations..

Upvotes: 9

Views: 8829

Answers (4)

Nicola Musatti
Nicola Musatti

Reputation: 18218

Although there isn't a standard way to do it, it is usually possible with implementation specific techniques. I did it a long time ago with Borland's C++ Builder. The idea is to declare your templates to be exported from the shared library where they need to reside and import them where they are used. The way I did it was along these lines:

// A.h
#ifdef GENERATE
#  define DECL __declspec(dllexport)
#else
#  define DECL __declspec(dllimport)
#endif

template <typename T> class DECL C {
};

// A.cpp
#define GENERATE
#include "A.h"

template class DECL A<int>;

Beware that I don't have access to the original code, so it may contain mistakes. This blog entry describes a very similar approach.

From your wording I suspect you're not on Windows, so you'll have to find out if and how this approach can be adopted with your compiler. I hope this is enough to put you in the right direction.

Upvotes: 0

Daniel Trebbien
Daniel Trebbien

Reputation: 39208

Yes. What you can do is explicitly instantiate the templates in CPP files using the compiler's explicit template instantiation syntax. Here is how to use explicit instantiation in VC++: http://msdn.microsoft.com/en-us/library/by56e477(v=VS.100).aspx. G++ has a similar feature: http://gcc.gnu.org/onlinedocs/gcc/Template-Instantiation.html#Template-Instantiation.

Note that C++11 introduced a standard syntax for explicit instantiation, described in [14.7.2] Explicit instantiation of the FDIS:

The syntax for explicit instantiation is:

explicit-instantiation:

externopt template declaration

Upvotes: 7

Mihails Strasuns
Mihails Strasuns

Reputation: 3803

C++ Shared Library with Templates: Undefined symbols error Some answers there cover this topic. To sum up short: it is possible if you force to instantiate templates in shared library code explicitly. It will require explicit specification for all used types for all used templates on shared lib side, though.

Upvotes: 3

Dirk is no longer here
Dirk is no longer here

Reputation: 368191

If it is really templates-only, then there is no shared library. See various Boost projects for concrete examples. Only when you have non-template code will you have a library. A concrete example is eg Boost Date_Time and date formatting and parsing; you can use the library with or without that feature and hence with or without linking.

Not having a shared library is nice in the sense of having fewer dependencies. The downside is that your binaries may get a little bigger and that you have somewhat higher compile-time costs. But storage is fairly cheap (unless you work in embedded systems are other special circumstances) and compiling is usually a fixed one-time cost.

Upvotes: 1

Related Questions