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

如何在CRTP模板中禁用拷贝赋值,仅允许引用接收generate返回值

问题根源

你之前的修改没有生效有两个核心原因:

  1. DerivedSignal sig = DerivedSignal::generate() 属于拷贝初始化语义,调用的是拷贝构造函数而非拷贝赋值运算符,你只删除赋值运算符自然不会拦截这个场景。
  2. 你写的拷贝赋值运算符签名不符合标准:常规拷贝赋值运算符的返回值是左值引用,你返回值类型的声明和编译器默认生成的拷贝赋值签名不匹配,相当于没有删除默认的拷贝赋值运算符,自然不生效。

可行实现方案

你只需要在CRTP基类SignalT中同时删除拷贝构造、移动构造、拷贝赋值、移动赋值四个函数即可,同时将基类的构造函数设为protected权限,仅允许子类访问:

template <class tDerivedSignal, class tBridgeType, class tPayLoadType = void>
class SignalT : public SignalSignatureT<tBridgeType>
{
protected:
    // 仅允许子类构造基类实例
    SignalT() = default;

public:
    // 删除拷贝/移动构造,直接拦截值接收的场景
    SignalT(const SignalT&) = delete;
    SignalT(SignalT&&) = delete;

    // 删除拷贝/移动赋值,拦截已有对象赋值覆盖的场景
    SignalT& operator=(const SignalT&) = delete;
    SignalT& operator=(SignalT&&) = delete;

    // ... 其余原有代码保持不变
    static tDerivedSignal &generate(tPayLoadType &fPayLoad)
    {
        tDerivedSignal &rtnVal = Pool::reserve();
        rtnVal.mPayLoad = fPayLoad;
        return rtnVal;
    }
    ...
};

效果验证

修改后:

  • 合法用法 DerivedSignal &sig = DerivedSignal::generate() 可以正常编译运行,没有任何影响
  • 非法用法 DerivedSignal sig = DerivedSignal::generate() 会直接触发编译报错,提示拷贝构造函数已被删除,完全符合要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 11:24:02