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



对于可选的template<class U = T> optional<T>& operator=(U&& v);,标准要求(参见[可选.分配]/3.16(:

除非。。。conjunction_v<is_scalar<T>, is_same<T, decay_t<U>>>就是false

为什么在分配类型为U == T的标量时必须排除大小写?

这是为了支持:

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

我们有一堆任务过载,其中包括:

  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将通过成为非模板而获胜。没问题。

最新更新