One approach is to extract the computation from this class into a separate one.
Then you can specialise only that computation class:
template <int a, int b>
class MyTemplateClass
{
// ....
void computeSomething() {
Computation<a, b> c;
c.compute();
}
};
template <int a, int b>
struct Computation { void compute () {} };
template <int a>
struct Computation<a, 2> { void compute () {} };
template <int a>
struct Computation<a, 3> { void compute () {} };
Though IMO it's better to not use specialisation, but instead different (descriptive!) names and a compile time conditional to choose between them:
template<bool Condition,
typename Then,
typename Else>
using if_t = typename std:: conditional<
Condition, Then, Else>:: type;
template <int a, int b>
class MyTemplateClass
{
// ....
using Computation =
if_t<b == 2,
B2Comp<a>,
if_t<b == 3,
B3Comp<a>,
DefaultComp<a, b> > >;
void computeSomething() {
Computation c;
c.compute();
}
};
// Add (template) classes, B3Comp and DefaultComp
If you can already try C++17, then above can be rewritten to:
template <int a, int b>
class MyTemplateClass
{
// ....
void computeSomething() {
if constexpr (b == 2) {
B2Comp<a> comp;
comp.compute();
} else if constexpr (b == 3) {
B3Comp<a> comp;
comp.compute();
} else {
DefaultComp<a, b> comp;
comp.compute();
// Or just put the code here, if it's short
}
}
};
Instead of template classes you could also use template functions.
In contrast to using a normal if this avoids evaluation of the "unneeded" code paths, thus making it possible to place otherwise ill-formed code there (like a recursive instantiation of the same template).