C++ 如何为模板类的const ref成员定义移动赋值运算符

C++ 如何为模板类的const ref成员定义移动赋值运算符,c++,c++11,language-lawyer,move-semantics,const-reference,C++,C++11,Language Lawyer,Move Semantics,Const Reference,我有以下模板类,其中成员是const ref type。对象复制已禁用,并且只希望具有“移动cntor”和“移动分配”操作符 Q1:如何正确地为const ref类型实现移动赋值运算符它是否正确,我做了什么 问题2:为什么会这样 MyClass<int> obj2(std::move(obj)); // will work with move ctor MyClass<int> obj3 = std::move(obj2); // also move ctor cal

我有以下模板类,其中成员是const ref type。对象复制已禁用,并且只希望具有“移动cntor”和“移动分配”操作符

Q1:如何正确地为const ref类型实现移动赋值运算符它是否正确,我做了什么

问题2:为什么会这样

MyClass<int> obj2(std::move(obj));   // will work with move ctor
MyClass<int> obj3 = std::move(obj2); // also move ctor called: Why?
第一:

MyClass<int> obj2(std::move(obj));   // will work with move ctor

第二点:

MyClass<int> obj3 = std::move(obj2); // also move ctor called: Why?

两者都在分别构造对象obj2和obj3并初始化它们。=在本上下文中并不意味着赋值。

第一个:

MyClass<int> obj2(std::move(obj));   // will work with move ctor

第二点:

MyClass<int> obj3 = std::move(obj2); // also move ctor called: Why?

两者都在分别构造对象obj2和obj3并初始化它们。=在本上下文中并不意味着赋值

Q1 您不能对常量和成员进行任何赋值。可以调用被引用对象的赋值运算符

问题2 这两个都是定义。两者都不是任务。C++有冗余语法。

第三季度 这不是未定义的行为。从对象移动的对象仍然是对象。移动int与复制int完全相同,因为更改源没有意义。MyClass从中移动时将打印空字符串

需要注意的是,运算符=没有成员初始化器,因为对象已经存在

您似乎只想移动std::reference\u包装器。我认为这不是一个好主意,因为你的动作实际上只是复制品。C++不允许你创建一个UNIQUY引用类型。我能想到的最接近的是std::unique_ptr,但即使如此,您也不能确保没有其他对底层对象的引用

Q1 您不能对常量和成员进行任何赋值。可以调用被引用对象的赋值运算符

问题2 这两个都是定义。两者都不是任务。C++有冗余语法。

第三季度 这不是未定义的行为。从对象移动的对象仍然是对象。移动int与复制int完全相同,因为更改源没有意义。MyClass从中移动时将打印空字符串

需要注意的是,运算符=没有成员初始化器,因为对象已经存在


您似乎只想移动std::reference\u包装器。我认为这不是一个好主意,因为你的动作实际上只是复制品。C++不允许你创建一个UNIQUY引用类型。我能想到的最接近的是std::unique_ptr,但即使如此,您也无法确保没有其他对底层对象的引用。更清楚地说,您无法轻松地将包含引用成员的对象移动到它所拥有的某些内容

如果它没有自己的内容,那么你当然可以简单地复制一份参考;但是,如果移动中的捐赠对象试图删除关于销毁的引用,那么您有一个问题,我们将进一步讨论

可能引用的目标内容本身可以移动,然后对象移动需要在引用上执行移动,创建该引用项的“活动”新实例并“杀死”原始对象

另一种选择是使用指针而不是引用。然后您可以轻松地移动指针,将施主指针设置为nullptr。您可以为指针创建一个包装器,将存根方法公开给引用(如果没有太多),以保持现有代码的功能。对值成员的任何直接使用都不能如此容易地混淆


一个非常弱的选择是在对象中有一个表示所有权的标志。移动时清除标志,如果清除标志,则销毁时不会销毁参考。缺点是,如果捐赠者在移动后没有立即删除,那么它就处于不一致的状态。已浅层移动的成员可能不再与仍可访问的引用内容兼容。

要清楚,您不能轻松地将包含引用成员的对象浅层移动到其拥有的某些内容

如果它没有自己的内容,那么你当然可以简单地复制一份参考;但是,如果移动中的捐赠对象试图删除关于销毁的引用,那么您有一个问题,我们将进一步讨论

可能引用的目标内容本身可以移动,然后对象移动需要在引用上执行移动,创建该引用项的“活动”新实例并“杀死”原始对象

另一种选择是使用指针而不是引用。然后您可以轻松地移动指针,将施主指针设置为nullptr。您可以为指针创建一个包装器,将存根方法公开给引用(如果没有太多),以保持现有代码的功能。对值成员的任何直接使用都不能如此容易地混淆

一个很弱的选择是
对象中表示所有权的标志。移动时清除标志,如果清除标志,则销毁时不会销毁参考。缺点是,如果捐赠者在移动后没有立即删除,那么它就处于不一致的状态。已被浅层移动的成员可能不再与仍可访问的引用内容兼容。

这很有帮助