How do I write a header for an instantiated template class in C++?

c++, header-files, instantiation, templates

Solution

You can define the template in your header file, declaring the methods, but without defining them. For example:

template <typename T>
class Foo {
    T val;
public:
    Foo (T t);
    T value ();
};

typedef Foo<double> Foo_d;
typedef Foo<float> Foo_f;

In the `.cpp` file, you complete the implementations of the methods, and then instantiate the templates that you want.

#include "foo_template.hpp"

template <typename T>
Foo<T>::Foo (T t) : val(t) {}

template <typename T>
T Foo<T>::value () { return val; }

template class Foo<double>;
template class Foo<float>;

The object file should have instantiations for `Foo_d` and `Foo_f` from the explicit instantiations of template `Foo`. Any other type used for template `Foo` will result in a linking error, since instantiations for them won't exist. Or, more pedantically, the compiler creates instantiations on demand as usual, but it won't be able to resolve the symbols corresponding to the methods of the class, because explicit instantiations for those won't exist.

Problem

I want to create a template class (let's call it `Foo`) that only accepts a few specific type parameters (let's say only `double` and `float`). Normally templates are implemented in the header file (`.h`) because it is unknown how it will be instantiated in user code. In this case, it makes more sense to implement the class in the implementation file (`.cpp`) like so: ``` // Foo.cpp: template <class T> class Foo { // Insert members here }; typedef Foo<double> Foo_d; typedef Foo<float> Foo_f; ``` This would instantiate and compile the class when Foo.cpp is compiled. But then how to I declare this in the header file without writing separate declarations for `Foo_d` and `Foo_f`?

Original source

Related problems