C++ 为什么移动构造函数影响可赋值?
刚从学校来@Angew告诉我,因为C++ 为什么移动构造函数影响可赋值?,c++,assignment-operator,move-constructor,C++,Assignment Operator,Move Constructor,刚从学校来@Angew告诉我,因为std::unique_ptr和std::unique_ptr是不同的类型,所以static_assert(不是std::is_assignable::value,”)。所以,我试着: template<typename T, typename D> struct MoveAssignOnly_V2 { MoveAssignOnly_V2& operator=(MoveAssignOnly_V2&) =
std::unique_ptr
和std::unique_ptr
是不同的类型,所以static_assert(不是std::is_assignable::value,”)代码>。所以,我试着:
template<typename T, typename D>
struct MoveAssignOnly_V2
{
MoveAssignOnly_V2&
operator=(MoveAssignOnly_V2&)
= delete;
MoveAssignOnly_V2&
operator=(MoveAssignOnly_V2&&) noexcept
{}
};
int main()
{
static_assert(not std::is_assignable_v<MoveAssignOnly_V2<int, float>,
MoveAssignOnly_V2<int, double>>);
}
,这让我有点困惑:既然它有这样一个角色,它怎么可能不可分配呢?所以我试着在MoveAssignOnly_V2
中添加这样的ctor,然后发布这个问题。这两个答案很好,但是,仍然无法解释为什么std::unique_ptr
既有移动赋值,又有此模板构造函数时不可赋值。接受以下代码:
MoveAssignOnly_V2<int, float> lhs;
MoveAssignOnly_V2<int, double> rhs;
lhs = stdL::move(rhs);
要解决问题中的更新,请执行以下操作:
不能单独使用函数声明,必须阅读完整的规范(在标准或规范中)。引用有关std::unique\u ptr的转换构造函数的链接参考:
此构造函数仅在满足以下所有条件时参与重载解析:
a) unique\u ptr::pointer
可隐式转换为pointer
b) U
不是数组类型
c) Deleter
是一种引用类型,E
与D
是同一类型,或者Deleter
不是一种引用类型,E
可以隐式转换为D
如您所见,必须实现unique_ptr
的转换构造函数,以便只有当源删除程序可以转换为目标删除程序时,它才处于活动状态。这与上一个问题中移动分配的规则基本相同。您在此处添加的内容:
template<class U, class E>
MoveAssignOnly_V2(MoveAssignOnly_V2<U, E>&& m) noexcept {}
模板
MoveAssignOnly_V2(MoveAssignOnly_V2&&m)无例外{}
不仅是一个移动构造函数,而且是一个模板化构造函数,可以从任何MoveAssignOnly\u V2
构造MoveAssignOnly\u V2
因此,从MoveAssignOnly\u V2>
构造MoveAssignOnly\u V2
很好。严格地说,它根本不是移动构造函数。您可能想称它为转换构造函数,它允许转换为可分配的类型。请查看问题中的更新。我注意到unique_ptr也有这样的转换构造函数,但是,与MoveAssignOnly_V2
不同,unique_ptr仍然是不可分配的。
MoveAssignOnly_V2<int, float> lhs;
MoveAssignOnly_V2<int, double> rhs;
lhs = stdL::move(rhs);
double lhs = 3.14;
float rhs = 42.f;
lhs = std::move(rhs);
template<class U, class E>
MoveAssignOnly_V2(MoveAssignOnly_V2<U, E>&& m) noexcept {}