Consider this class template:
template <typename T1, typename T2, bool B>
class SomeClass { };
Now, I'd like to provide two implementations based on B==true
and B==false
. That is, I'd like to say something like:
template <ANYTHING, ANYTHING, true> class SomeClass {
// First implementation
};
template <ANYTHING, ANYTHING, false> class SomeClass {
// Second implementation
};
How can this be done in C++(11)?
With partial specialization:
// primary
template<typename X, typename Bool>
struct Foo;
template<typename X>
struct Foo<X, std::true_type> {};
template<typename X>
struct Foo<X, std::false_type> {};
// use
Foo<X, std::true_type> x;
I use a type-wrapper for bool
, but you can also do that with
non-type template parameters:
// primary
template<typename, bool>
struct Foo;
template<typename X>
struct Foo<X, true> {};
template<typename X>
struct Foo<X, false> {};
// use
Foo<X, true> x;
Sometimes you can compute the value used for partial specialization with meta-programming in the default argument:
// primary
template<typename X, typename is_integral_ = std::is_integral<X>::type>
struct Foo;
This makes the configuration variable overridable by user choice.
struct my {};
Foo<my, std::true_type> x;
To prevent that, dispatch through inheritance:
// primary, where Foo_impl is any of the above
template<typename X>
struct Foo : public Foo_impl<X> {};
It's called partial specialization:
template <typename T1, typename T2> class SomeClass<T1 ,T2, true> {
// First implementation
};
template <typename T1, typename T2> class SomeClass<T1, T2, false> {
// Second implementation
};
As the name indicates it is related to (full) specialization which looks like this:
template <> class SomeClass<int, char, false> {
// dedicated version for T1=int, T2=char, B=false
};
Note that if most of the implementation is the same, you can also write a single generic version, where only that code which depends on the bool argument is delegated to a trait class. In this case, the trait class would be fully-specialized on a single argument.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With