* template <int dim> * class X { * // do something on subdim-dimensional sub-objects of the big * // dim-dimensional thing (for example on vertices/lines/quads of * // cells): * template <int subdim> void f(); * }; * * template <int dim> * template <> * void X<dim>::f<0> () { ...operate on the vertices of a cell... } * * template <int dim, int subdim> void f(X<dim> &x) { * x.f<subdim> (); * } *
The problem is: the language doesn't allow us to specialize X::f()
without specializing the outer class first. One of the common tricks is therefore to use something like this:
* template <int N> struct int2type {}; * * template <int dim> * class X { * // do something on subdim-dimensional sub-objects of the big * // dim-dimensional thing (for example on vertices/lines/quads of * // cells): * void f(int2type<0>); * void f(int2type<1>); * void f(int2type<2>); * void f(int2type<3>); * }; * * template <int dim> * void X<dim>::f (int2type<0>) { ...operate on the vertices of a cell... } * * template <int dim> * void X<dim>::f (int2type<1>) { ...operate on the lines of a cell... } * * template <int dim, int subdim> void f(X<dim> &x) { * x.f (int2type<subdim>()); * } *
Note that we have replaced specialization of X::f()
by overloading, but that from inside the function g()
, we can still select which of the different X::f()
we want based on the subdim
template argument.