mik*_*ike 29 c++ language-lawyer move-semantics c++11 c++14
为什么我允许std::move在包含具有已删除移动语义的类型的字段的类上使用(情况1),但是不允许在这样的类的实例上使用它(情况2)?
我理解案例2.我已经明确删除了移动构造函数,所以如果我试图移动它,我会收到错误.但我希望在案例1中也会出现这种情况,这样的类也在被移动.
class TestNonMovable {
std::string ss;
public:
TestNonMovable(){}
TestNonMovable(const TestNonMovable&) {}
TestNonMovable(TestNonMovable&&) = delete;
};
class SomeClass {
TestNonMovable tnm;
};
int main() {
// case1: This compiles, my understanding is that for SomeClass::tnm compiler will use copy constrctor
SomeClass sc1;
SomeClass sc2 = std::move(sc1);
// case2: This does not compile, move constructor is explicitly deleted, compiler will not try using copy constructor
TestNonMovable tnm;
TestNonMovable tnm2 = std::move(tnm); //error: use of deleted function 'TestNonMovable::TestNonMovable(TestNonMovable&&)'
}
Run Code Online (Sandbox Code Playgroud)
son*_*yao 45
注意两个类之间的区别.对于TestNonMovable(情况2),您显式地将移动构造函数声明为delete.随着TestNonMovable tnm2 = std::move(tnm);被删除的举动构造函数重载决策选择,然后会导致错误.
对于SomeClass(情况1),您没有显式声明移动和复制构造函数.复制构造函数将被隐式声明和定义,但移动构造函数将被隐式声明并定义为已删除,因为它具有不可移动的数据成员.请注意,已删除的隐式声明的移动构造函数不会参与重载解析.使用SomeClass sc2 = std::move(sc1);,复制构造函数被选中,然后代码工作正常.返回的rvalue引用std::move也可以绑定到对const(也const SomeClass&)的lvalue-reference .
重载解析会忽略已删除的隐式声明的移动构造函数(否则会阻止rvalue的复制初始化).(自C++ 14起)
BTW:在两种情况下都允许使用std :: move本身.它不执行移动操作,只是将参数转换为rvalue.在两种情况下,移动操作都发生在施工中.
| 归档时间: |
|
| 查看次数: |
1767 次 |
| 最近记录: |