C++ : union of two types without virtual base class inheritance

标签 c++ c++14

是否可以在不手动创建交集类型的情况下创建两种类型的并集?

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

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

class port;

class module0 {
    port a,b,c;
}

class module1 {
    port c,d,e;
}

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

class top_level_module {
    port a,b,c,d,e;
}

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

class top_level_module : union_type < module0, module1 > {
    //  port a,b,c,d,e;
}

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

// 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;
}

最佳答案

您可以使用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{};
}

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

mod.module1::c

换句话说,该成员并没有被删除,它被顶层类中的using声明隐藏了。

这种方法有一些缺点。例如:

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

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

struct top_level_module: private module0, private module1 {
    using module0::a;
    using module0::b;
    using module0::c;
    using module1::d;
    using module1::e;
};

确实很冗长。

关于C++ : union of two types without virtual base class inheritance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41049290/

相关文章:

c++ - Mac 上的 OpenMP 不再工作

c++ - 为什么 std::make_unique 而不是 std::unique_ptr::make?

c++ - 是否可以为 std::array 类型添加自己的构造函数?

c++ - 如何将 back_inserter 与转换结合起来,C++

c++ - 如何制作空字符?

c++ - 按下触摸屏会触发mousePressEvent,如何判断是鼠标点击还是触摸屏点击?

c++ - 为什么在空指针上调用 "operator delete"时会调用 "delete"?

c++ - 是否有更好(更有效)的方法来查找是否可以从另一个字符串的字符形成一个字符串?

c++ - 重用构造函数。将右值传递给 const 左值并且不重复执行

c++ - 转发声明一个 constexpr 变量模板