C++11 C++;11对象为成员的类的移动赋值运算符-初学者级别
我有一个关于c++11中移动辅助的初学者问题。假设我有一个a级,配备了移动辅助操作符:C++11 C++;11对象为成员的类的移动赋值运算符-初学者级别,c++11,move,C++11,Move,我有一个关于c++11中移动辅助的初学者问题。假设我有一个a级,配备了移动辅助操作符: class A { public: A(); ~A(); A& operator=(A&&); ... } 我还有一个包含a类对象的B类,并提供了一个移动赋值操作符 class B { public: B(); ~B(); B& operator=(B&&); ... private: A Test
class A
{
public:
A();
~A();
A& operator=(A&&);
...
}
我还有一个包含a类对象的B类,并提供了一个移动赋值操作符
class B
{
public:
B();
~B();
B& operator=(B&&);
...
private:
A Test;
}
我的想法是,B移动分配运算符将调用其成员的移动分配运算符,因此我尝试了以下方法:
B& B::operator=(B&& Other)
{
...
Test = Other.Test;
...
return *this;
}
B& B::operator=(B&& Other)
{
...
Test = std::move(Other.Test);
...
return *this;
}
但这不起作用,因为类A的移动赋值未被调用
相反,我能够通过使用以下方法使程序工作:
B& B::operator=(B&& Other)
{
...
Test = Other.Test;
...
return *this;
}
B& B::operator=(B&& Other)
{
...
Test = std::move(Other.Test);
...
return *this;
}
我不明白为什么第一种方法不起作用。我在想,既然构造函数将调用其成员构造函数,那么move赋值操作符也应该这样做。我是错了还是我的代码出错了?谁能解释一下,谢谢
Other.Test
不是右值表达式,因为它有一个名称。OTOHstd::move(Other.Test)
具有类型A
和值类别xvalue(即右值)。因此,它可以绑定到move构造函数
(编辑:无耻地复制了@dyp的评论。谢谢,@dyp和@KerrekSB。)
其他。Test
不是右值表达式,因为它有一个名称。OTOHstd::move(Other.Test)
具有类型A
和值类别xvalue(即右值)。因此,它可以绑定到move构造函数
(编辑:无耻地复制了@dyp的评论。谢谢,@dyp和@KerrekSB。)
其他。Test
不是右值表达式,因为它有一个名称。OTOHstd::move(Other.Test)
具有类型A
和值类别xvalue(即右值)。因此,它可以绑定到move构造函数
(编辑:无耻地复制了@dyp的评论。谢谢,@dyp和@KerrekSB。)
其他。Test
不是右值表达式,因为它有一个名称。OTOHstd::move(Other.Test)
具有类型A
和值类别xvalue(即右值)。因此,它可以绑定到move构造函数
(编辑:厚颜无耻地复制了@dyp的评论。谢谢,@dyp和@KerrekSB。)@Pradhan是正确的-您需要使用
std::move
在move assignment操作符的实现中移动成员。但是,如果这是实现移动构造函数所需的全部内容,则可以声明运算符以使用默认实现:
#include <memory>
class A {
public:
A() : p{} { }
~A() { }
A &operator=(A &&) = default;
// Instead of:
// A &operator=(A &&other) {
// p = std::move(other.p);
// return *this;
// }
private:
std::unique_ptr<int> p;
};
int main() {
A a;
A b;
b = std::move(a);
return 0;
}
#包括
甲级{
公众:
A():p{}{}
~A(){}
A&运算符=(A&&)=默认值;
//而不是:
//A&运算符=(A&&其他){
//p=标准::移动(其他.p);
//归还*这个;
// }
私人:
std::唯一的ptr p;
};
int main(){
A A;
A b;
b=标准::移动(a);
返回0;
}
@Pradhan是正确的-您需要使用std::move
在move赋值操作符的实现中移动成员。但是,如果这是实现移动构造函数所需的全部内容,则可以声明运算符以使用默认实现:
#include <memory>
class A {
public:
A() : p{} { }
~A() { }
A &operator=(A &&) = default;
// Instead of:
// A &operator=(A &&other) {
// p = std::move(other.p);
// return *this;
// }
private:
std::unique_ptr<int> p;
};
int main() {
A a;
A b;
b = std::move(a);
return 0;
}
#包括
甲级{
公众:
A():p{}{}
~A(){}
A&运算符=(A&&)=默认值;
//而不是:
//A&运算符=(A&&其他){
//p=标准::移动(其他.p);
//归还*这个;
// }
私人:
std::唯一的ptr p;
};
int main(){
A A;
A b;
b=标准::移动(a);
返回0;
}
@Pradhan是正确的-您需要使用std::move
在move赋值操作符的实现中移动成员。但是,如果这是实现移动构造函数所需的全部内容,则可以声明运算符以使用默认实现:
#include <memory>
class A {
public:
A() : p{} { }
~A() { }
A &operator=(A &&) = default;
// Instead of:
// A &operator=(A &&other) {
// p = std::move(other.p);
// return *this;
// }
private:
std::unique_ptr<int> p;
};
int main() {
A a;
A b;
b = std::move(a);
return 0;
}
#包括
甲级{
公众:
A():p{}{}
~A(){}
A&运算符=(A&&)=默认值;
//而不是:
//A&运算符=(A&&其他){
//p=标准::移动(其他.p);
//归还*这个;
// }
私人:
std::唯一的ptr p;
};
int main(){
A A;
A b;
b=标准::移动(a);
返回0;
}
@Pradhan是正确的-您需要使用std::move
在move赋值操作符的实现中移动成员。但是,如果这是实现移动构造函数所需的全部内容,则可以声明运算符以使用默认实现:
#include <memory>
class A {
public:
A() : p{} { }
~A() { }
A &operator=(A &&) = default;
// Instead of:
// A &operator=(A &&other) {
// p = std::move(other.p);
// return *this;
// }
private:
std::unique_ptr<int> p;
};
int main() {
A a;
A b;
b = std::move(a);
return 0;
}
#包括
甲级{
公众:
A():p{}{}
~A(){}
A&运算符=(A&&)=默认值;
//而不是:
//A&运算符=(A&&其他){
//p=标准::移动(其他.p);
//归还*这个;
// }
私人:
std::唯一的ptr p;
};
int main(){
A A;
A b;
b=标准::移动(a);
返回0;
}
@dyp我不明白。当我的意思是说std::move(Other.Test)
返回一个右值引用时,说它有类型右值引用是不正确的吗?@Pradhan:正确的说法是“std::move(Other.Test)
是一个右值”。它的类型是A
std::move
返回一个右值引用,但任何表达式类型的任何引用限定符都会立即删除以形成值类别。例如,表达式std::move(Other.Test)
具有类型A
和值类别xvalue(即,一个右值)。@dyp:为了恰当地迂腐,您不能“返回引用”(因为函数调用确实是表达式)。相反,您可以说“std::move的返回类型是一个右值引用”,或者“std::move
返回一个xvalue”。@KerrekSB您可能是对的,但我想知道函数返回类型是否真的是技术语言。它在库部件中多次出现;但不是在核心语言部分(“返回一个ref”)--Mystd::move
标识一组函数模板,而不是一个表达式。@dyp我不懂。当我的意思是说std::move(Other.Test)
返回一个右值引用时,说它有类型右值引用是不正确的吗?@Pradhan