【问题标题】:Why does std::optional::operator=(U&&) require U to be a non-scalar type?为什么 std::optional::operator=(U&&) 要求 U 是非标量类型?
【发布时间】:2019-04-02 19:00:22
【问题描述】:

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

【问题讨论】:

  • 可能是因为另一个重载就可以了。查看单个重载并不能真正为您提供全貌
  • 类型都是特殊情况...,但基本类型和特别是 void 非常无聊!

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


【解决方案1】:

这是为了支持:

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

我们有一堆assignment overloads,分别是:

  1. nullopt_t
  2. optional const&amp;
  3. optional&amp;&amp;
  4. U&amp;&amp;
  5. optional&lt;U&gt; const&amp;
  6. optional&lt;U&gt;&amp;&amp;

对于标量,具体来说,#4 将是标准转换,而其他任何内容都是用户定义的转换 - 所以它是最佳匹配。但是,这样做的结果将是分配o 以使用0 的值。这意味着o = {} 可能意味着不同的东西,具体取决于T 的类型。因此,我们排除了标量。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-15
    • 2016-07-21
    • 1970-01-01
    • 2013-09-22
    • 2021-01-02
    • 1970-01-01
    相关资源
    最近更新 更多