Reputation: 4435
I have a helper class R<T>
, and some classes T
inherit it. I want to declare some function f(T t)
for those classes which do not inherit R<T>
. This is done easily with SFINAE:
template<typename T>
class R {};
class Good : public R<Good> {};
class Bad {};
template<typename T>
auto f(T /* t */) -> typename std::enable_if<
!std::is_base_of<R<T>, T>::value>::type
{
// do something
}
int main() {
f(Good()); // compilation error
f(Bad()); // OK
}
Now I have some other class Derived
which inherits Good
. It does not inherit R<Derived>
though. Still, I do not want to declare f(Derived)
.
class Derived : public Good {};
int main() {
f(Derived()); // OK, but should be compilation error
}
So, what I want to check for type T
is that T
is a descendant of some R<P>
where P
is some parent of T
.
Is it possible to do it with SFINAE? I'd like to stay within the scope of C++11.
Although I'm really interested in how to solve this general problem, in my exact case there is one simplification: I know that among all parents of T
there is at most one R<P>
for any P
. Any solution for this simplification is also appreciated.
Upvotes: 2
Views: 210
Reputation: 4435
Seems that I solved it, thanks to this answer:
template<template<typename> class Base, typename Derived>
struct SmartBaseOf {
private:
template<class Intermediate>
static auto test(const Base<Intermediate>&) -> typename std::enable_if<
std::is_base_of<Intermediate, Derived>::value &&
std::is_base_of<Base<Intermediate>, Intermediate>::value,
std::true_type>::type;
static std::false_type test(...);
public:
constexpr static bool value = decltype(test(Derived()))::value;
};
template<typename T>
auto f(T /* t */) -> typename std::enable_if<
!SmartBaseOf<R, T>::value>::type
{
// do something
}
Upvotes: 2