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