C++:没有虚基类继承的两种类型的联合

ran*_*dom 5 c++ c++14

是否可以创建两种类型的并集而无需手动创建交集类型?

问题是我的上下文中的交集类完全没有意义,因此创建它会使代码用户感到困惑.

我的实际案例:我正在描述一个数字硬件模拟器,它是许多模块的分层树状结构:

class port;

class module0 {
    port a,b,c;
}

class module1 {
    port c,d,e;
}
Run Code Online (Sandbox Code Playgroud)

我需要创建这两种类型的联合:

class top_level_module {
    port a,b,c,d,e;
}
Run Code Online (Sandbox Code Playgroud)

我想应该有一些技术来创建一个联合类型(这是我要问的问题):

class top_level_module : union_type < module0, module1 > {
    //  port a,b,c,d,e;
}
Run Code Online (Sandbox Code Playgroud)

但我没有找到任何.我在网上找到的唯一解决方案是虚拟继承:

// this is a meaningless type in my context
class intersection_of_module0_module1 { 
    port c;
}

class module0: virtual intersection_of_module0_module1 {
    port a,b;
}

class module1: virtual intersection_of_module0_module1 {
    port d,e;
}

class top_level_module : module0, module1 {
    //  port a,b,c,d,e;
}
Run Code Online (Sandbox Code Playgroud)

sky*_*ack 4

您可以使用using 声明c并从两个结构之一提升该字段。
举个例子:

struct port {};

struct module0 { port a, b, c; };
struct module1 { port c, d, e; };


struct top_level_module: module0, module1 {
    using module0::c;
};

int main() {
    top_level_module mod;
    mod.c = port{};
}
Run Code Online (Sandbox Code Playgroud)

它并不完全是两种类型的联合,但它有助于c通过 a消除使用的歧义top_level_module
从用户的角度来看,top_level_module看起来它有 5 个显式且可访问的字段,分别名为abc和。 此外,它还有一个额外的数据成员,可通过完全限定名称进行命名和访问:de
c

mod.module1::c
Run Code Online (Sandbox Code Playgroud)

换句话说,该成员并未被删除,它已被顶级类中的 using 声明隐藏。

这种方法有一些缺点。举个例子:

  • 您实际上并没有消除额外的字段。因此它将被默认初始化,您必须意识到这样做的后果。
  • 的用户top_level_module仍然可以以某种方式使用隐藏成员。
  • 您不能对 进行聚合初始化top_level_module
  • ...

如果您想更进一步并限制对底层类的访问,您可以使用私有继承并显式导出所需的字段:

struct top_level_module: private module0, private module1 {
    using module0::a;
    using module0::b;
    using module0::c;
    using module1::d;
    using module1::e;
};
Run Code Online (Sandbox Code Playgroud)

确实很冗长。