You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

继承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; // 移除默认初始化,改为在构造函数中控制
};

逻辑说明

  1. 默认构造:显式定义默认构造函数,将isError初始化为false,对应示例中的c对象;
  2. 模板构造函数:通过std::enable_if限制仅接受非Feedback的类型,只要该类型能转换为基类TaggedUnion,就会调用基类构造并将isError设为true,覆盖了原继承的基类构造函数逻辑,对应示例中的a、b对象;
  3. 同类型赋值:使用默认的拷贝/移动赋值运算符,会自动拷贝源对象的所有成员(包括isError),对应示例中的d = b;
  4. 模板赋值运算符:同样限制非Feedback类型,调用基类赋值逻辑后设置isError为true,覆盖了原继承的基类赋值运算符。

这种方式无需为TaggedUnion的每个模板参数单独编写代码,通过模板统一处理所有符合条件的类型。

内容的提问来源于stack exchange,提问作者ZeroZ30o

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 01:35:16