2

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.

1 Answer 1

2

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
}   
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.