使用 SFINAE 检查模板参数继承

Checking template parameter inheritance with SFINAE

本文关键字:参数 继承 SFINAE 检查 使用      更新时间:2023-10-16

我有一个R<T>的辅助类,有些类T继承它。我想为那些不继承R<T>的类声明一些函数f(T t)。使用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
}

现在我还有其他一些继承Good的类Derived。不过,它不会继承R<Derived>。不过,我不想宣布f(Derived).

class Derived : public Good {};
int main() {
    f(Derived()); // OK, but should be compilation error
}

因此,我想检查类型 T 的是T是某个R<P>的后代,其中PT的某个父级。

可以用SFINAE做到这一点吗?我想保持在 C++11 的范围内。

虽然我对如何解决这个一般问题真的很感兴趣,但在我的确切情况下,有一个简化:我知道在所有T父母中,任何P最多有一个R<P>。这种简化的任何解决方案也值得赞赏。

似乎我解决了它,这要归功于这个答案:

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
}