【问题标题】:How do I remove a special constructor from overload resolution?如何从重载决议中删除特殊构造函数?
【发布时间】:2021-11-25 04:41:31
【问题描述】:

我正在 C++14 中创建 C++17 的 std::optional<class T> 的实现。规范规定,如果T 不是可移动构造的,则移动构造函数应从重载决议中排除,如果T 可简单地移动构造,则移动构造函数应被排除在外。我一直坚持使用前者。

这是我目前所拥有的代码示例:

    template<class T, bool = is_trivially_move_constructible_v<T>>
    class optional_move_construct : public optional_copy_construct<T> {
    public:
      optional_move_construct(optional_move_construct&& rhs) :
        optional_base<T>() {
        if (rhs.m_full) {
          _impl_construct(std::move(rhs.m_value));
        }
      }
    };

optional_copy_construct&lt;T&gt; 是我正在使用的继承链的一部分,所以我不会担心。

有两种方法可以“删除”移动构造函数,这两种方法都不适用于这种情况。

选项 1: 删除移动构造函数。这不起作用,因为已删除的函数包含在重载决议中。
选项 2: 使用 SFINAE 从重载决议中排除移动构造函数。这也不起作用,因为 SFINAE 需要一个模板函数才能工作,而且它的优先级低于默认的移动构造函数。

我该怎么做呢?

【问题讨论】:

标签: c++ template-meta-programming overload-resolution


【解决方案1】:

移动构造函数有一个T&amp;&amp; 参数,可能还有其他参数,前提是这些参数具有默认值。这意味着您可以将 std::enable_if_t&lt;Condition, int&gt; = 0 添加为移动构造函数的附加参数。

当你有两个参数的移动构造函数时,编译器不会创建一个参数为 optional::optional(T&amp;&amp;) 的移动构造函数。

【讨论】:

  • 但是被删除的构造函数不会仍然参与重载决议吗?
  • @VainMan:不,如果它被删除,它不是过载集的一部分。
  • 你的意思是不声明还是声明为= delete;? IIRC,后者将参与重载决议,将是最佳匹配。
  • 我错了。这是模棱两可的。 godbolt.org/z/MExM7Pq4h
  • @VainMan:更新
猜你喜欢
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-29
  • 1970-01-01
  • 2015-04-26
相关资源
最近更新 更多