为什么std :: optional :: operator =(U &&)要求U为非标量类型?

时间:2018-10-29 19:20:45

标签: c++ language-lawyer c++17 optional

对于可选的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的标量时必须排除大小写?

1 个答案:

答案 0 :(得分:20)

这是为了支持:

optional<int> o(42);
o = {}; // <== we want this to reset o

我们有一堆assignment overloads,其取值:

  1. nullopt_t
  2. optional const&
  3. optional&&
  4. U&&
  5. optional<U> const&
  6. optional<U>&&

对于标量,具体来说,#4将是标准转换,而其他则将是用户定义的转换-因此这将是最佳匹配。但是,这样做的结果是将o赋值给0。这将意味着o = {}可能根据T的类型具有不同的含义。因此,我们排除了标量。

对于非标量,#4和#3将等效(都是用户定义的转换),而#3将成为非模板而获胜。没问题。