Specialization and C ++ template output

When using the template:

class A {...} class B : A {...} class C : A {...} template<typename T> class D{...} 

I need T to be only B or C. Which means that T must be a derivative of A.

Is there any way to do this? Thanks!

+4
source share
3 answers

Use std::is_base_of along with std::enable_if :

 template<typename T, typename X = std::enable_if<std::is_base_of<A, T>::value>::type> class D{...} 

Note that it will accept any T if it is derived from A If you need T be either B or C , you need to change it and use std::is_same or / and std::conditional along with std::enable_if .

You can make it clean like:

 template<typename T, typename Unused = extends<T,A>> class D{...} 

where extends is defined as:

 template<typename D, typename B> using extends = typename std::enable_if<std::is_base_of<B,D>::value>::type; 

static_assert can also be used (as other answers showed) if you want it to lead to an error and compilation failure. However, if you need to choose or deselect, say, for many specializations, use the above approach.

Hope this helps.

+5
source

You can use static_assert in combination with std::is_base_of :

 #include <type_traits> class A {}; class B : A {}; class C : A {}; class X{}; template<typename T> class D { static_assert(std::is_base_of<A,T>::value, "T must be derived from A"); }; int main() { D<C> d_valid; D<X> d_fails; // compilation fails return 0; } 

live on ideone

+5
source

Yes, this one has to do this:

 template<typename T> class D { static_assert(std::is_base_of<A,T>::value, "not derived from A"); // ... }; 

Demo is here.

But this is not the idea of โ€‹โ€‹templates. If you write boilerplate code, then it should be general, Ie work for all types that support the actions that you apply to them.

+1
source

All Articles