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

为何std::expected<T,E>要求可拷贝赋值的T必须可拷贝构造?

为什么std::expected<T, int>不可拷贝赋值,即便T可拷贝赋值?

你的T类型禁用了拷贝构造但保留了拷贝赋值,所以单独看T,std::is_copy_assignable_v<T>为true是合理的——毕竟已经存在的T对象之间能正常赋值。但std::expected<T, E>的拷贝赋值逻辑要复杂得多,核心原因在于它要处理两种状态之间的转换:

关键:std::expected的赋值必须覆盖所有状态组合

std::expected要么存着一个T类型的有效值,要么存着一个E类型的错误值。拷贝赋值得处理下面四种情况:

  • 源和目标都存有效值:直接对T做拷贝赋值,这步你的T能搞定。
  • 源和目标都存错误值:直接对E做拷贝赋值,这里int完全没问题。
  • 源存有效值,目标存错误值:这时候目标得先销毁当前的错误值,然后用源的T拷贝构造一个新的T对象(因为目标之前根本没有T的实例)。但你的T禁用了拷贝构造,这一步直接卡壳,整个赋值操作没法完成。
  • 源存错误值,目标存有效值:目标销毁当前的T,然后拷贝构造E的错误值,这步int也没问题。

正是第三种场景的存在,要求T必须同时支持拷贝构造和拷贝赋值——否则当目标处于错误状态时,没法从源的有效值构造出自己的T成员,标准自然不会让std::expected<T,E>的拷贝赋值生效。

移动赋值的情况完全同理

如果T可移动赋值但不可移动构造,当目标是错误状态、源是右值的有效值时,目标需要移动构造T对象,这一步会因为T不可移动构造而失败。所以std::expected的移动赋值也要求T同时支持移动构造和移动赋值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:22:48