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

继承std::optional<T>的operator=在T为原生类型时失效问题问询

继承std::optional<T>时原生类型赋值的歧义问题

我在包装std::optional<T>以添加自定义实用函数时,遇到一个问题:当T为原生类型时,将T类型值赋值给自定义可选类型变量会触发编译错误。原本预期通过using std::optional<T>::operator =;继承的赋值运算符能处理T类型的赋值,但在T是原生类型的场景下(对应代码中的BUG宏),GCC和LLVM都无法匹配到正确的继承运算符。显式提供并转发operator=(T const&)和operator=(T&&)(对应UNBUG宏)可修复该问题。非原生类型时继承的赋值运算符能正常工作,仅原生类型出现此问题。

测试代码

#include <optional>

template <typename T>
class my_optional : public std::optional<T>
    {
        public:
            // 尝试继承所有成员
            using std::optional<T>::optional;
            using std::optional<T>::operator =;
            my_optional             (                           ) =default;
            my_optional             (my_optional      const& opt) =default;
            my_optional             (my_optional          && opt) =default;
            my_optional& operator = (my_optional      const& opt) =default;
            my_optional& operator = (my_optional          && opt) =default;
            my_optional             (std::optional<T> const& opt) : std::optional<T>(          opt ) {};
            my_optional             (std::optional<T>     && opt) : std::optional<T>(std::move(opt)) {};
            my_optional& operator = (std::optional<T> const& opt) { std::optional<T>::operator = (          opt ); return *this; };
            my_optional& operator = (std::optional<T>     && opt) { std::optional<T>::operator = (std::move(opt)); return *this; };

#ifdef UNBUG
            my_optional& operator = (T const& var) { std::optional<T>::operator = (          var ); return *this; };
            my_optional& operator = (T     && var) { std::optional<T>::operator = (std::move(var)); return *this; };
#endif
            
            // my_optional(int, int)    {} // 测试用的随机构造函数
    };


#ifdef BUG
    using my_alias = int;
#else
    struct my_struct {};
    using my_alias = my_struct;
#endif


void my_func()
    {
        my_optional<my_alias> an_opt;
        
        my_alias a_var;
        an_opt = a_var;
    }

编译情况

  • clang++ -std=c++26 -c -o /dev/null -x c++ inherit-optional-bug-3.cpp:编译成功
  • clang++ -std=c++26 -c -o /dev/null -x c++ inherit-optional-bug-3.cpp -DBUG -DUNBUG:编译成功
  • clang++ -std=c++26 -c -o /dev/null -x c++ inherit-optional-bug-3.cpp -DBUG:编译失败,报错如下:
inherit-optional-bug-3.cpp:42:10: error: use of overloaded operator '=' is ambiguous (with operand types 'my_optional<my_alias>' (aka 'my_optional<int>') and 'my_alias' (aka 'int'))
   42 |                 an_opt = a_var;
      |                 ~~~~~~ ^ ~~~~~
inherit-optional-bug-3.cpp:14:17: note: candidate function
   14 |                         my_optional& operator = (my_optional          && opt) =default;
      |                                      ^
inherit-optional-bug-3.cpp:18:17: note: candidate function
   18 |                         my_optional& operator = (std::optional<T>     && opt) { std::optional<T>::operator = (std::move(opt)); return *this; };
      |                          

疑问

此现象是符合C++标准预期?还是标准库缺陷?或是实现问题?亦或是GCC和LLVM均存在bug?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 16:57:30