对于可选的template<class U = T> optional<T>& operator=(U&& v);
,标准要求(请参见[optional.assign]/3.16):
该函数不得参与重载解析,除非 ...
conjunction_v<is_scalar<T>, is_same<T, decay_t<U>>>
是false
...
为什么在分配类型为U == T
的标量时必须排除大小写?
答案 0 :(得分:20)
这是为了支持:
optional<int> o(42);
o = {}; // <== we want this to reset o
我们有一堆assignment overloads,其取值:
nullopt_t
optional const&
optional&&
U&&
optional<U> const&
optional<U>&&
对于标量,具体来说,#4将是标准转换,而其他则将是用户定义的转换-因此这将是最佳匹配。但是,这样做的结果是将o
赋值给0
。这将意味着o = {}
可能根据T
的类型具有不同的含义。因此,我们排除了标量。
对于非标量,#4和#3将等效(都是用户定义的转换),而#3将成为非模板而获胜。没问题。