继承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
相关产品推荐
相关产品推荐

