c++ - 使用 SFINAE 检查模板参数继承

标签 c++ c++11 templates inheritance sfinae

我有一个助手类 R<T>和一些类(class) T继承它。我想声明一些函数 f(T t)对于那些不继承 R<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
}

现在我还有其他类(class)Derived它继承Good 。它不继承R<Derived>尽管。尽管如此,我还是不想声明f(Derived) .

class Derived : public Good {};

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

所以,我想检查类型 TT是一些 R<P> 的后代哪里PT 的某个家长.

可以用 SFINAE 来做吗?我希望保持在 C++11 的范围内。

虽然我真的对如何解决这个普遍问题很感兴趣,但在我的具体案例中,有一个简化:我知道在 T 的所有 parent 中最多有一个R<P>对于任何 P 。任何用于这种简化的解决方案也将受到赞赏。

最佳答案

看来我解决了它,感谢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
}   

关于c++ - 使用 SFINAE 检查模板参数继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42830311/

相关文章:

c++ - 我可以强制可变参数模板采用特定类型的参数吗

C++ - 从客户端代码中隐藏模板参数

c++ - Eclipse 中类的多重定义错误

c++ - Xcode 推断命名空间?

c++ - 将字符串添加到 vector<string> 循环时内存损坏

c++ - 在 C++ 中添加字符串和文字的问题

c++ - 只接受指针类型参数的模板

c++ - 部分模板参数应用程序的部分模板特化不适用于 GCC 4.8.1

c++ - Qt 设计器中的自定义布局

c++ - 如何通过索引从可变模板参数包中提取值?