SFINAE 和可变参数模板类

Edw*_*win 3 c++ templates template-meta-programming variadic-templates c++11

我正在创建一个class C从可变数量的类继承的。定义了这些类的列表,例如:A,B。在函数中,class C我需要从所有基类调用函数,但对象可以是C<A,B>C<A>或者C<B>如果我调用class Ain 的函数,C<B>我会得到一个错误。这是类的示例以及我如何尝试解决问题:

    class A
    {
        int a;
    public:
        virtual void set_a(const int &value)
        {
            a = value;
        }
    protected:
        virtual int get_a()
        {
            return this->a;
        }
    };
    class B
    {
        int b;
    public:
        virtual void set_b(const int &value)
        {
            b = value;
        }
    protected:
        virtual int get_b()
        {
            return this->b;
        }
    };
    template<class ...T>
    struct Has_A
    {
        template<class U = C<T...>>
        static constexpr bool value = std::is_base_of < A, U > ::value;
    };

    template<class ...T>
    class C :
         virtual public T...
    {
    public:
    #define HAS_A Has_A<T...>::value

        void f()
        {
    #if HAS_A<>
            auto a = this->get_a();
    #endif
        auto b = this->get_b();
        cout << HAS_A<>;
    }
};
Run Code Online (Sandbox Code Playgroud)

当我调用f()对象时,C<A,B>它会跳过调用get_a()但输出是true.

最初,我写了这个

template<class U = C<T...>>
typename std::enable_if<!std::is_base_of<A, U>::value, int>::type get_a()
{
    return -1;
}
template<class U = C<T...>>
typename std::enable_if<std::is_base_of<A,U>::value, int>::type get_a()
{
    return A::get_a();
}
Run Code Online (Sandbox Code Playgroud)

但我不想为Aand 的所有函数重写这个B。让我们假设A有 10 个以上的功能。

有什么漂亮的解决方案吗?

PS对不起我的英语。我以前从未使用过 SFINAE。基本上我有一堆基因,我想为它们写一个方便的包装,在那里人们可以配置他希望生物体拥有的基因。

bip*_*pll 5

在当前标准中,这是微不足道的:

void f() {
    if constexpr(Has_A<T...>::value) {
        auto a = get_a();
    }
    auto b = get_b();
}
Run Code Online (Sandbox Code Playgroud)