Your approach is a valid C++ code and should work both in C++03 and C++11. It is called explicit instantiation:
template struct Point<2>;
While applying to class templates it explicitly instantiates all members of a class template for some template argument list in the current translation unit. With this approach it is simple to create the libraries of templates for which the set of possible template arguments is known in advance (as in your case when Point
can be 2D and 3D but not 1D, 4D etc.).
In C++11 when you add to explicit instantiation directive keyword extern
:
extern template struct Point<2>;
it becomes a declaration, not a definition. The behavior of such thing is similar to usual extern
keyword for variables. Explicit template instantiation declaration can be used together with explicit instantiation in the following manner:
// point.h
template <int dim> struct Point {
...
void foo();
...
};
extern template struct Point<2>;
extern template struct Point<3>;
#include "point.hpp"
// point.hpp
#include "point.h"
template <int dim>
void Point<dim>::foo() {
...
}
// point.cpp
#include "point.hpp"
template struct Point<2>;
template struct Point<3>;
With such code you achieve the same result as with your one but additionally you allow the users of your code to use Point<1>
, Point<4>
and other specializations of a Point
class template if they want. Without extern template struct Point<2>;
and extern template struct Point<3>;
directives Point
class template would be implicitly instantiated in the users code even for template arguments 2
and 3
that reduces the meaning of explicit instantiation (template struct Point<2>;
and template struct Point<2>;
).