class A{};
class B : public A{};
template <typename T>
void test(const T& t)
{
std::cout << "template\n";
}
template <>
void test<A>(const A& t)
{
std::cout << "specialization\n";
}
int main()
{
test(B{});
return 0;
}
When the code above is ran it prints "template" because the compiler interprets T as B but is it possible to tell the compiler to never allow T to be a derivation of A and thereby making it call the specialization instead ( so that it prints "specialization" on any types that are derived from A)?
#include <iostream>
#include <type_traits>
#include <typeinfo>
#include <new>
template < typename BASE, typename T >
typename std::enable_if< !std::is_base_of<BASE,T>::value >::type
test( const T& ) { std::cout << "primary template\n" ; }
template < typename BASE, typename T >
typename std::enable_if< std::is_base_of<BASE,T>::value >::type
test( const T& v )
{
[[maybe_unused]] const BASE& b = v ;
// use b
std::cout << "specialisation for BASE (" << typeid(BASE).name()
<< ") and classes derived from BASE\n" ;
}conststruct my_base_class {} bbbb ;
conststruct my_derived_class : my_base_class {} dddd ;
int main()
{
const std::bad_alloc eeee ;
test<my_base_class>(bbbb) ; // type of bbbb == my_base_class
// specialisation for BASE (my_base_class) and classes derived from BASE
test<my_base_class>(dddd) ; // type of dddd is a class derived from my_base_class
// specialisation for BASE (my_base_class) and classes derived from BASE
test<std::exception>(dddd) ; // type of dddd is not a class derived from std::exception
// primary template
test<my_base_class>(eeee) ; // type of eeee is not a class derived from my_base_class
// primary template
test<std::exception>(eeee) ; // type of eeee is a class derived from std::exception
// specialisation for BASE (std::exception) and classes derived from BASE
}