Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么移动构造函数影响可赋值?_C++_Assignment Operator_Move Constructor - Fatal编程技术网

C++ 为什么移动构造函数影响可赋值?

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&) =

刚从学校来@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&)
        = 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 {}