C++ 当T不可移动构造时,为什么std::optional的移动构造函数没有被删除?

C++ 当T不可移动构造时,为什么std::optional的移动构造函数没有被删除?,c++,optional,move-constructor,C++,Optional,Move Constructor,根据标准,std::optional的复制构造函数: …应定义为删除,除非是可复制的\u v是真的 但是std::optional的move构造函数: …不得参与过载解决,除非可移动\u可构造\u v为真 正如我所说,不删除std::optional的move构造函数的目的是允许这样的代码: std::optional<X> o1; std::optional<X> o2(std::move(o1)); std::可选o1; 标准:可选氧气(标准:移动(o1)); …

根据标准,
std::optional
的复制构造函数:

…应定义为删除,除非
是可复制的\u v
真的

但是
std::optional的move构造函数:

…不得参与过载解决,除非
可移动\u可构造\u v

正如我所说,不删除
std::optional
的move构造函数的目的是允许这样的代码:

std::optional<X> o1;
std::optional<X> o2(std::move(o1));
std::可选o1;
标准:可选氧气(标准:移动(o1));
…要依靠某些转换序列工作-
o2
将由类型为
A
的对象构造,该对象已使用
std::optional&&
构造(如果我错了,请更正我)

但是关于
std::optional
的可能构造函数,我很难找到一个可以匹配这个用例的构造函数


如果
T
不可移动构造,为什么不删除
std::optional
的移动构造函数?

明确删除它意味着它将是 值,从而导致编译时错误,而不是 复制构造函数处理这些案例

例:

显式删除的函数仍参与重载 分辨率,并且可以是最佳匹配。这可能是有用的,
例如,禁用某些转换。

委员会真的不关心可复制但不可移动的可憎内容。例如,见对的讨论,该讨论将此类类型描述为“病理性”,并将早期的支持尝试描述为“疯狂”

一般来说,这类东西的默认措辞是“不得参与过载解决”,除非有某种特殊原因来捕获调用(这有时是适当的,例如,但可能会导致不良副作用,例如)。对于copy special成员,这在概念之前无法完成,因此必须使用“定义为已删除”。对于move特殊成员,OTOH“定义为已删除”不够精确,因为“显式删除的移动”和“默认移动隐式定义为已删除”:后者不参与重载解析


另请参见。

的讨论。因此,只有当
T
可复制但不可移动时,才允许从x值构造
可选的
。@Holt:没错。如果
T
不可移动,如何声明移动构造函数以将其从重载解析中排除?当
=default
?@MaartenBamelis时,这取决于您如何实现
optional
-由于某些限制,您不能(始终)将
T
的实例直接存储到
optional
对象中(特别是如果
T
不是默认可构造的),因此,在
可选
中使用
=default
没有多大意义。你必须依靠类型特征和SFINAE。@MaartenBamelis:部分专业化可能是最好的,请参阅
#include <utility>

struct X
{
    X() = default;
    X(const X&) = default;
    X(X&&) = delete;
};

int main()
{
    X a;
    X b(std::move(a));
}
'X::X(X &&)': attempting to reference a deleted function