Give template specialization of base a higher precedence than derivations?

Hello,
In the below code, is it possible to give the template specialization of A a higher precedence than any derived types of A?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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)?
Last edited on
Something like this (SFINAE), perhaps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#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" ;
}

const struct my_base_class {} bbbb ;
const struct 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
}

http://coliru.stacked-crooked.com/a/0e1b2878183d38e7
https://rextester.com/XPD87015
Topic archived. No new replies allowed.