关于std::optional赋值运算符(4)(5)(6)的类型匹配疑问
基于cppreference中std::optional::operator=的重载(4)(5)(6),结合std::optional是管理可选值的类模板这一前提,提出以下技术疑问:
重载(4)的参与条件要求:C20前为
std::decay_t<U>不是std::optional<T>,C20起为std::remove_cvref_t<U>不是std::optional<T>;同时std::is_constructible_v<T,U>、std::is_assignable_v<T&,U>必须为true;还要满足T是非标量类型,或者std::decay_t<U>≠T。既然std::optional<T>和T是不同类型(下方测试代码可验证),这个条件和构造/赋值特性的关联是什么?当T是非标量且std::decay_t<U>≠T时,这个赋值是如何生效的?重载(5)(6)要求T无法从任何(const)
std::optional<U>类型表达式构造、转换或赋值(对应12个类型特性均为false),同时分别要求:重载(5)需要std::is_constructible_v<T,const U&>、std::is_assignable_v<T&,const U&>为true;重载(6)需要std::is_constructible_v<T,U>、std::is_assignable_v<T&,U>为true。如果std::optional<U>等于U,这个赋值如何生效?是否需要假设std::optional<T/U>没有有效值才能解释这些矛盾?
测试代码
#include<optional> #include<type_traits> #include<string> #include<ios> #include<iostream> using std::optional; using std::is_same; using std::string; using std::boolalpha; using std::cout; using std::endl; int main (){ optional<string> opt("yes"); string s("yeah"); cout << boolalpha << is_same<decltype(opt),decltype(s)>::value << endl; return 0; }
内容的提问来源于stack exchange,提问作者Vinod

