【发布时间】:2021-07-03 11:57:24
【问题描述】:
我在一个项目中坚持使用 c++17,所以我无权访问指定的初始化程序。我有一堆联合类型,我想避免以这种方式初始化(因为它很烦人):
MyUnionType x;
x.value = value_set_for_all_union_members;
我想要这个
MyUnionType x(value_set_for_all_union_members);
但我也想避免为我创建的每个联合编写实现。我知道我所有的联合类型都将具有以下结构,每个联合都意味着实际上代表位字段,所以我实际上确实想要在这里进行类型修剪,我知道根据 C++ 它是“UB”,但是在 C++ 委员会中,在 C 中它不是未定义的行为,因此我关心的所有编译器都会在这里做我想做的事情。
union Example{
integer_type value;
custom_safe_bitfield_abstraction<...> a;
custom_safe_bitfield_abstraction<...> b;
...
};
我想,好吧,我将只继承构造函数,并使用 CRTP 提取适当的integer_type。当然我不能直接继承联合,所以我选择了这个策略:
struct Example : Base<Example>{
union{
integer_type value;
custom_safe_bitfield_abstraction<...> a;
custom_safe_bitfield_abstraction<...> b;
...
};
};
使用匿名联合,我应该能够像以前一样使用它(example.value 应该是联合内部的值)。
然后在实现中我执行以下操作:
template<class Derived_T>
struct Base{
using value_type = decltype(Derived_T::value);
explicit Base(value_type v){
static_cast<Derived_T*>(this)->value = v;
}
}
但这不起作用:
error: Incomplete type 'Example' used in nested name specifier
> using value_type = decltype(Derived_T::value);
显然,我们不允许在声明成员之前引用它。好的...但是必须有某种方法可以将类型数据提取出来,毕竟我不关心任何内存对齐或任何事情。
我唯一能想到的另一件事是在 CRTP 模板参数中包含类型(即Base<Derived_T, value_type>),但我想避免这样做。我想有一些方法可以在每个派生类上编写函数或指定内部类型,我也不想这样做(而且有点违背了我正在做的事情的目的)。
有没有办法避免为每个类编写构造函数,并且不牺牲我的其他代码重复最小化目标?
【问题讨论】:
-
我认为你可以使用模板函数而不是继承。
-
工厂函数
-
@GaryNLOL 你能详细说明一下吗?我想我仍然有“需要从模板中查找成员变量的类型”的问题。
-
FWIW,在 C++ 中通过联合进行类型双关是非法的。我还没有看到编译器不符合大多数人的期望,但你在 UB 领域。根据您实际在做什么/想要什么,
std::variant是您可以使用的类型安全联合类型。 -
@NathanOliver 我想要类型修剪,因为我正在通过它们实现安全位域,我不想存储互斥类型
标签: c++ templates c++17 unions crtp