基于两个交互类的基于模板的多重继承... [英] Variadic template-based multiple inheritance for two interacting classes...

查看:174
本文介绍了基于两个交互类的基于模板的多重继承...的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我目前的项目中,我需要能够提供基于模板的多重继承(Mixin模式)和有两个类(镜像多继承树),可以一起交互(即一个使用来自同一继承关系的另一个方法)。

In my current project, I need to be able to provide template-based multiple inheritance (Mixin pattern) and have two classes (with mirroring multiple-inheritance trees) that can interact together (i.e. one uses methods from the other one at the same inheritance level).

很长的故事,我似乎找不到一个优雅的方式来构建这个。以下是简化的测试用例(您可以直接此处)运行和编辑它。

Long story short, I cannot seem to find an elegant way to build this. Below is a reduced testcase (you can run and edit it directly here).

有没有模式或技巧,让我有类似于注释行的东西,同时保持任何子类相对无麸质?

Is there a pattern or trick that would let me have something similar to the commented line while keeping any subclasses relatively cruft-free?

显然,嵌套的 Thing 类需要从提供必要的接口方法的另一个类继承。但是任何修复继承问题(CRTP ...)的尝试总是似乎导致我递归继承或不完全的基本类型问题...

Obviously, the nested Thing class would need to inherit from another class providing the necessary interface methods. However any attempt at fixing the inheritance problem (CRTP...) always seem to lead me to recursive inheritance or incomplete base type issues...

class Base {
public:

    class Thing {
    public:
        Thing(Base& b) : _b(b) {};

        Thing& operator+= (const Thing p) { _b.add(*this, p); return *this; };

        int k;
    protected:
        Base& _b;
    };

    void add(Thing &d, const Thing s) { d.k += s.k; }
};

template <class... Interfaces>
class Extensible : virtual public Base, virtual public Interfaces... {

    class Thing : virtual public Base::Thing, virtual public Interfaces::Thing... {

    };
};

class SomeInterface : Base {
    void multiply(Thing &d, const Thing s) { d.k *= s.k; }

    class Thing : public Base::Thing {
        Thing& operator*= (const Thing p) {
            //_b.multiply(*this, p); return *this; // <-- won't work of course
        };

    };

};

int main() {
    Extensible<SomeInterface> a;
    return 0;
}


推荐答案

http://ideone.com/KhLyfj (我只是告诉基类它的子类是 _b 正确的类型)。在某些情况下它不工作。您可以尝试将 Thing / 移动模板直接移动到 Base

This is one of the options: http://ideone.com/KhLyfj (I just tell the base class what is its subclass to give _b a correct type). It won't work in some situations though. You can experiment with moving the template from Thing/add straight to Base.

class Base {
public:

    template<typename Outer>
    class Thing {
    public:
        Thing(Base& b) : _b(b) {};

        Thing& operator+= (const Thing p) { _b.add(*this, p); return *this; };

        int k;
    protected:
        Outer& _b;
    };

    template<typename Outer>
    void add(Thing<Outer> &d, const Thing<Outer> s) { d.k += s.k; }
};

template <class... Interfaces>
class Extensible : virtual public Base, virtual public Interfaces... {

    class Thing : virtual public Base::Thing<Base>, virtual public Interfaces::template Thing<Base>... {

    };
};

class SomeInterface : Base {
    void multiply(Thing<SomeInterface> &d, const Thing<SomeInterface> s) { d.k *= s.k; }

    class Thing : public Base::Thing<SomeInterface> {
        Thing& operator*= (const Thing p) {
            _b.multiply(*this, p); return *this; // <-- will work of course
        };

    };

};

int main() {
    Extensible<SomeInterface> a;
    return 0;
}

这篇关于基于两个交互类的基于模板的多重继承...的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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