1

I have some classes in C++ that I want to make a static library out of. One of the classes is a hash table class that uses the other two to create the object. I've tried following another small demonstration in the answer to another question, but the library I produce doesn't seem to be defining anything i've written in the test program. I've tried all the declarations & implementations in both a single file and separated into headers/source, but the arrangement doesn't seem to matter. How do I get my classes into a static libHash.a?

Community
  • 1
  • 1
Brenton Poke
  • 131
  • 2
  • 5

2 Answers2

4

Distributing templates in object form doesn't work very well, because the compiler isn't able to create new instantiations. Users of your library will only have access to template instantiations defined in the library.

That's why template classes and functions are usually implemented in header files.

See also Why can templates only be implemented in the header file?

Community
  • 1
  • 1
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Is there a way to create the library if the classes weren't templated? – Brenton Poke May 05 '12 at 01:16
  • @Brenton: Does your application first link correctly if you pass in the object files directly? – Ben Voigt May 05 '12 at 01:18
  • Well, I just passed an object file containing only the classes to the compiler along with the main.cpp that's supposed to use them, but it doesn't link. If I create and object file out of the entire program (along with the class #includes) that object file will produce the intended program just fine. – Brenton Poke May 05 '12 at 02:06
  • @BrentonPoke: I suspected as much. Your problems have nothing to do with creation of a static library. Did you read the question I linked in my answer? – Ben Voigt May 05 '12 at 02:56
  • Yes, so I think I might just give up on this side project and leave them as a header file. – Brenton Poke May 05 '12 at 09:29
1

You can put template instantiations in a library, but templates must be in headers. If you know in advance which specializations of the templates you want to instantiate then you can declare explicit instantiations in the headers and then define those explicit instantiations in the .cpp that gets compiled and put into the .a

// hash.h

template<typename T> struct Hash { };
// declare explicit instantiation
extern template class Hash<int>;

// Hash.cpp

#include <Hash.h>
// define explicit instantiation
template class Hash<int>;

But for instantiations you can't know in advance (e.g. Hash<SomeOtherPersonsType>) you can't instantiate it and so can't put it in the library.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • It's best to note that this is a C++11 feature. In C++03 some compilers allowed `extern` to be used this way, at least for function templates, but pure declarations and support for static libraries are a new feature of the language. – Potatoswatter May 06 '12 at 19:01
  • Yes, it's true that isn't valid in C++03 but all major compilers have supported extern templates for years, for class templates as well as function templates (the N1448 proposal to add it to C++ states "This feature has been implemented in compiler front ends offered by Edison Design Group, GCC, IBM, Metrowerks, and Microsoft" and that was in 2003.) Static libraries are not a new feature, they're not mentioned in either C++98 or C++11, but predate both by many years :-) – Jonathan Wakely May 06 '12 at 19:43
  • OK, didn't realize it was already well supported for classes, +1. – Potatoswatter May 07 '12 at 03:46