9

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..

lytenyn
  • 819
  • 5
  • 21
  • Do you mean "finite" or "bounded"? Obviously anything you do on a computer, or in this universe, is going to be finite, so the distinction is crucial. – Kerrek SB Sep 08 '11 at 13:53
  • I meant bounded: we will need instantiations of these templates for about 8 types and no more. So we could easily write down a list. – lytenyn Sep 08 '11 at 14:02
  • Hmm, I'm not entirely sure, and you'll certainly have to ship the actual headers, but you could add explicit instantiations for those types to a source file and compile that and declare those templates `extern` everywhere else. I've never tried this, but I think this is supposed to have the desired effect. – Kerrek SB Sep 08 '11 at 14:05

4 Answers4

7

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

Community
  • 1
  • 1
Daniel Trebbien
  • 38,421
  • 18
  • 121
  • 193
3

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.

Community
  • 1
  • 1
Mihails Strasuns
  • 3,783
  • 1
  • 18
  • 21
1

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.

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
0

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.

Nicola Musatti
  • 17,834
  • 2
  • 46
  • 55