可变参数模板的多重继承:如何为每个基类调用函数? [英] Multiple inheritance with variadic templates: how to call function for each base class?

查看:95
本文介绍了可变参数模板的多重继承:如何为每个基类调用函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个钻石继承计划,其中最后一个孩子应该能够从许多不同的父母那里继承。

I have a diamond inheritance scheme, where the last child should be able to inherit from many different parents.

     A
    /|\
   / | \
  B  C  ...
  |  |  |
    * *
    D E

现在想象我有一个 D类:公共B E类:公共B,公共C ,等等。来自 D 我想调用其所有父对象的相同函数,由于继承,我保证该函数存在。我的想法是我可以将其包装在可变参数的模板中。

Now imagine I have a class D : public B, class E : public B, public C, etc. From D I want to call the same function of all its parents, which I am guaranteed exists due to the inheritance. My thought was that I could wrap this in some variadic template.

当前,我有以下内容:

template <typename T>
class A
{
public:
    A(T t) : mT(t) {}
    virtual ~A() {}
    virtual void doThings() = 0;
protected:
    T mT;
};

template <typename T, typename A = A<T>>
class B : public A
{
public:
    B(T t) : A(t) {}
    virtual ~B() {}
    virtual void doThings() { std::cout << "B" << std::endl; }
};

template <typename T, typename A = A<T>>
class C : public A
{
public:
    C(T t) : A(t) {}
    virtual ~C() {}
    virtual void doThings() { std::cout << "C" << std::endl; }
};

现在我想我可以做这样的事情,但显然不起作用:

Now I thought I could do something like this, which obviously does not work:

template <typename T, typename ...Args>
class ChildGenerator : public Args...
{
public:
    ChildGenerator(T t) : Args(t)... {}

    // The unpacking of the variadic template does not work here.
    // Do I need to make it recursive somehow? How can I do that without having to instantiate new classes B and C?
    void doThings() override { Args...::doThings();}
};

我希望我可以这样使用它:

My hope is that I can use it like so:

int main()
{
    using B = B<double>;
    using C = C<double>;
    B c1(0.0);
    C c2(1.0);
    ChildGenerator<double, B, C> c3(2.0);
    c1.doThings();
    c2.doThings();
    c3.doThings();
 }

预期产量(顺序无关紧要):

Expected output (order does not matter):

B
C
B // <-- order of these two does not matter
C // <--

我要实现的目标是可能的吗?

Is what I'm trying to achieve possible?

推荐答案

一种迭代可变参数基数的方法:

One way to iterate over the variadic bases:

template <typename T, typename ...Args>
class ChildGenerator : public Args...
{
public:
    ChildGenerator(T t) : Args(t)... {}

    void doThings() override {
        int dummy[] = {0, (Args::doThings(), void(), 0)...};
        static_cast<void>(dummy); // avoid warning for unused variable
    }
};

或在C ++ 17中,带有折叠表达式:

or in C++17, with folding expression:

    void doThings() override {
        (static_cast<void>(Args::doThings()), ...);
    }

这篇关于可变参数模板的多重继承:如何为每个基类调用函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆