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

删除特殊成员的自定义类型的std::variant赋值运算符哪个编译器正确?

编译器行为差异判定结论

应当信任GCC和Clang的处理结果,MSVC此处的实现不符合C++标准要求。

问题复现

测试代码如下:

#include <variant>

struct A { 
  A() = default;
  A(A&&) = delete;
};

struct B { 
  B() = delete;
  B(A&&) {};
};

int main() {
  std::variant<A, B> v{};
  v = A{};
}

原因说明

  • 调用v = A{}时,重载决议会匹配std::variant的模板赋值运算符template<class T> variant& operator=(T&&),首先会确定可选类型中匹配的目标类型:由于当前variant默认初始化后持有A类型实例,且A支持从右值A构造,因此选中目标类型为A,不会触发到B的类型转换。
  • 该赋值运算符的实现要求,当目标类型的赋值操作无法保证不抛出异常时,需要采用「先构造临时对象、再移动构造到variant存储」的强异常安全实现逻辑,而A的移动构造函数已经被显式删除,无法完成移动操作,因此该赋值运算符是不可用的,代码理应编译失败。
  • MSVC的实现未正确检查移动构造函数的可用性,属于不符合C++标准的实现缺陷。

内容的提问来源于stack exchange,提问作者康桓瑋

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 20:39:02