如何从重载决议中删除一个特殊的构造函数?

How do I remove a special constructor from overload resolution?

我正在 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<T> 是我正在使用的继承链的一部分,所以我不会担心它。

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

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

我该怎么做?

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

当你有 two-argument 移动构造函数时,编译器不会创建 one-argument optional::optional(T&&) 移动构造函数。