Compile a header-only template library into a shared library?

We are in the process of developing a new C ++ library and decided to go based on templates, as well as with some specific specializations of a partial template for corner cases. In particular, it will be a header-only template library .

Currently, there is some concern that this will lead to a lot of duplication of code in binary files, since the library of this template will be compiled into any other shared library or executable file that uses it (maybe only those parts that are used ) I still think this is not a problem (in particular, the compiler can even embed those things that it cannot use for the borders of the shared library).

However, since we know the final set of types for which it will be used, is there a way to compile this header into a library and provide another header only with declarations and nothing else? Please note that the library should contain not only general implementations, but also partial specializations.

+8
c ++ templates shared-libraries
source share
4 answers

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

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

The syntax for an explicit instance is:

explicit specification:

extern opt template Announcement

+6
source share

C ++ shared library with templates: Undefined character error Some answers there cover this topic. In short: this is possible if you force the creation of templates in the code of the shared library explicitly. However, for all used templates, for all used templates on the shared side, an explicit specification for all types used is required.

+3
source share

If these are really just templates, then there is no shared library. For specific examples, see Various Boost Projects. Only if you have code without a template will you have a library. A specific example: for example, Boost Date_Time and date formatting and parsing; you can use the library with or without this function, and therefore with or without a binding.

Not having a shared library is nice in the sense of having fewer dependencies. The disadvantage is that your binaries can get a little more and that you have slightly higher compilation times. But storage is pretty cheap (if you don’t work on embedded systems, these are other special circumstances), and compilation is usually a fixed one-time cost.

+1
source share

Although there is no standard way to do this, it is usually possible using specific implementation methods. I did this a long time ago with Borland C ++ Builder. The idea is to announce that your templates will be exported from the shared library where they need to live and import them where they are used. The way I did this was as follows:

 // Ah #ifdef GENERATE # define DECL __declspec(dllexport) #else # define DECL __declspec(dllimport) #endif template <typename T> class DECL C { }; // A.cpp #define GENERATE #include "Ah" template class DECL A<int>; 

Remember that I do not have access to the source code, so it may contain errors. This blog post describes a very similar approach.

From your wording, I suspect that you are not on Windows, so you will need to figure out how and how this approach can be adopted with your compiler. Hope this is enough to put you in the right direction.

0
source share

All Articles