c++ - 为什么 std::optional::operator=(U&&) 要求 U 是非标量类型?
问题描述
对于可选的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
?
解决方案
这是为了支持:
optional<int> o(42);
o = {}; // <== we want this to reset o
我们有一堆赋值重载,它们需要:
nullopt_t
optional const&
optional&&
U&&
optional<U> const&
optional<U>&&
具体来说,对于标量,#4 将是标准转换,而其他任何东西都将是用户定义的转换 - 所以它将是最佳匹配。但是,这样做的结果将是赋值o
为0
. 这意味着这o = {}
可能意味着不同的事情,具体取决于T
. 因此,我们排除了标量。
对于非标量,#4 和#3 将是等价的(都是用户定义的转换),而#3 将通过成为非模板而获胜。那里没问题。
推荐阅读
- flutter - Flutter:更改命名构造函数参数的名称
- android - 应用中的多个或一个前台服务
- joomla3.0 - 插入/更新数据库时 Joomla 时区错误
- arrays - 优化数组算法以找到 j 的最大值 - i 受到 A[i] <= A[j] 的约束
- xpath - 在里面获取文本
之前和之后
- css - 如何在 jupyter notebook 上的 R 中设置默认图像/绘图大小?
- javascript - 有没有办法在Firefox中实现图像的平滑过渡?这在 chrome 上效果很好
- angular - Angular 应用程序已成功部署在 Azure 上,但访问时出现权限被拒绝消息
- go - resp.Body 的内容存储在哪里?
- reactjs - React-redux 中的动作和动作类型是什么意思?