是否可以在不手动创建交集类型的情况下创建两种类型的并集?
问题是在我的上下文中交集类是完全没有意义的,所以创建它会使代码用户感到困惑。
我的实际案例: 我正在描述一个数字硬件模拟器,它是许多模块的分层树状结构:
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 个显式且可访问的字段,名为 a
、b
、c
、d
和 e
。
此外,它还有一个名为 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/