继承operator=与构造函数时,自动设置isError状态的实现方法
问题描述
我定义了如下结构体:
struct Feedback : public TaggedUnion<Feedback1Idx, String> { using TaggedUnion<Feedback1Idx, String>::TaggedUnion; using TaggedUnion<Feedback1Idx, String>::operator=; bool isError = false; };
该结构体继承了TaggedUnion的构造函数与operator=,因此可以编写如下代码:
Feedback a = Feedback1Idx(); Feedback b = String(); Feedback c = Feedback(); Feedback d = b;
我希望上述示例中a.isError为true、b.isError为true、c.isError为false(d.isError为true,因为b.isError为true)。换句话说:
- 用
Feedback1Idx/String构造或赋值Feedback时,isError设为true; - 默认构造的
Feedback,isError为false; - 同类型赋值时,
isError随源对象拷贝。
要求无需为TaggedUnion<>的每个模板参数单独添加构造函数/赋值运算符。
解决方案
可以通过模板构造函数+模板赋值运算符的方式统一处理所有可转换/赋值给基类的类型,同时保留默认构造和同类型赋值的特殊逻辑,代码实现如下:
#include <type_traits> // 需要用到 enable_if 和 is_same struct Feedback : public TaggedUnion<Feedback1Idx, String> { // 默认构造:显式初始化 isError 为 false Feedback() : isError(false) {} // 模板构造函数:处理所有非 Feedback 类型的转换构造 template<typename T, typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, Feedback>>> Feedback(T&& val) : TaggedUnion<Feedback1Idx, String>(std::forward<T>(val)), isError(true) {} // 同类型拷贝/移动赋值:使用默认实现,自动拷贝 isError Feedback& operator=(const Feedback&) = default; Feedback& operator=(Feedback&&) = default; // 模板赋值运算符:处理所有非 Feedback 类型的赋值 template<typename T, typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, Feedback>>> Feedback& operator=(T&& val) { // 调用基类的赋值逻辑 TaggedUnion<Feedback1Idx, String>::operator=(std::forward<T>(val)); // 设置 isError 为 true isError = true; return *this; } bool isError; // 移除默认初始化,改为在构造函数中控制 };
逻辑说明
- 默认构造:显式定义默认构造函数,将
isError初始化为false,对应示例中的c对象; - 模板构造函数:通过
std::enable_if限制仅接受非Feedback的类型,只要该类型能转换为基类TaggedUnion,就会调用基类构造并将isError设为true,覆盖了原继承的基类构造函数逻辑,对应示例中的a、b对象; - 同类型赋值:使用默认的拷贝/移动赋值运算符,会自动拷贝源对象的所有成员(包括
isError),对应示例中的d = b; - 模板赋值运算符:同样限制非
Feedback类型,调用基类赋值逻辑后设置isError为true,覆盖了原继承的基类赋值运算符。
这种方式无需为TaggedUnion的每个模板参数单独编写代码,通过模板统一处理所有符合条件的类型。
内容的提问来源于stack exchange,提问作者ZeroZ30o
相关产品推荐
相关产品推荐

