为什么std :: optional :: operator =(U&)要求U是非标量类型? [英] Why does std::optional::operator=(U&&) require U to be a non-scalar type?
问题描述
对于可选的模板< class U = T>可选的< T& operator =(U& v);
标准要求(请参阅 [optional.assign] /3.16 ):
For optional's template<class U = T> optional<T>& operator=(U&& v);
the standard demands that (see [optional.assign]/3.16):
该函数不得参与重载解析,除非
...
conjunction_v
...
This function shall not participate in overload resolution unless ...
conjunction_v<is_scalar<T>, is_same<T, decay_t<U>>>
isfalse
...
为什么在分配标量时必须排除大小写类型 U == T
?
Why do we have to exclude case when assigning a scalar of type U == T
?
推荐答案
存在的目的在于: / p>
This exists to support:
optional<int> o(42);
o = {}; // <== we want this to reset o
我们有一堆分配超载,其花费为:
We have a bunch of assignment overloads, which take:
-
nullopt_t
-
可选const&
-
可选&&
-
U&& ;
-
optional< U> const&
-
可选< U>&
nullopt_t
optional const&
optional&&
U&&
optional<U> const&
optional<U>&&
对于标量,具体来说,#4将是标准转换,而其他则将是用户定义的转换-因此这将是最佳匹配。但是,这样做的结果是将 o
分配给值为 0
的用户。这意味着 o = {}
可能根据 T
的类型可能具有不同的含义。因此,我们排除了标量。
For scalars, specifically, #4 would be a standard conversion whereas anything else would be a user-defined conversion - so it would be the best match. However, the result of that would be assigning o
to be engaged with a value of 0
. That would mean that o = {}
could potentially mean different things depending on the type of T
. Hence, we exclude scalars.
对于非标量,#4和#3等效(都是用户定义的转换),而#3将成为非模板而获胜。没问题。
For non-scalars, #4 and #3 would be equivalent (both user-defined conversions), and #3 would win by being a non-template. No problem there.
这篇关于为什么std :: optional :: operator =(U&)要求U是非标量类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!