I am trying to write a pair of overloaded functions, one that must be called for a pointer to a type that is not a B or a child of B, and the second must be called for pointers to B and children of B. At first I tried to use specialization of the template for B, but this doesn't work for derived classes of B. So I looked up SFINAE and enable_if etc but couldn't get it to work.
The signature of the generic function is
(1) template<typename T> int f(T *t)
For the other I tried to use enable_if and is_base_of like so:
(2) template<typename T> int f(typename enable_if<is_base_of<B, T>::value, T>::type *t)
but always (1) gets called. I tried to replace (1) by the negation of (2):
(1b) template<typename T> int f(typename enable_if<!is_base_of<B, T>::value, T>::type *t)
and now I get errors for all Ts whether or not they are (children of) B.
What am I doing wrong? What is the solution?
Test code is as follows:
#include <type_traits>
#include <iostream>
using namespace std;
class B {};
class D : public B {};
class C {};
// (1)
/* template<typename T>
int f(T *t)
{ cout << "T\n"; } */
// (1b)
template<typename T>
int f(typename enable_if<!is_base_of<B, T>::value, T>::type *t)
{ cout << "T\n"; }
// (2)
template<typename T>
int f(typename enable_if<is_base_of<B, T>::value, T>::type *t)
{ cout << "B\n"; }
int main()
{
B b;
D d;
C c;
f(&b); // Want B; get T with (1), dont compile with (1b)
f(&d); // Want B; get T with (1), dont compile with (1b)
f(&c); // Want T; get T with (1), dont compile with (1b)
return 0;
}
Aucun commentaire:
Enregistrer un commentaire