移动构造函数和右值引用
Move constructors and rvalue references
class Foo {
int m_num;
public:
Foo() {}
Foo(int& n) {m_num = n;}
Foo(int&& n) {m_num = n;}
Foo(const Foo& src) {m_num = src.m_num;}
Foo(Foo&& src) {m_num = src.m_num;}
Foo& operator =(const Foo& src) {
m_num = src.m_num;
return *this;
}
Foo& operator =(Foo&& src) {// move
m_num = src.m_num;
return *this;
}
int& operator =(const int& src) {return m_num = src;}
int& operator =(int&& src) {return m_num = src;}
};
为什么当我调用Foo f4(Foo(2));
时,它调用Foo(int&& n)
构造函数而不是构造函数Foo(Foo&& src)
? 另外,为什么传递 num 这是一个右值引用调用移动构造函数? 例如,Foo f = num
不调用移动构造函数。
int main() {
int&& num = 5;
/*int num{ 5 };*/ // initializer-list
Foo f = num; // custom constructor
f = num; // assignment operator
Foo f2 = 6; // custom move constructor
f2 = 10; // custom move assignment
f2 = f; // assignment operator
Foo f3(f); // custom constructor
// f3(f2); // ERROR
f3 = (f2); // assignment operator
Foo f4(Foo(2));
在Foo(2)
中,整数是一个右值,需要一个来自int&&
的右值引用构造函数。
在以下情况下
Foo f = num; // custom constructor
不调用右值构造函数,因为命名值永远不会被视为右值。您必须调用std::move(num)
才能使其正常工作。
该标准以这种方式定义它,以避免在意外移动命名值并在以后使用时混淆情况。您必须明确移动,即使变量是右值引用也是如此。
编辑
根据cpp首选项,c ++ 17编译器必须省略复制/移动构造函数(即在这种情况下,它不得调用或要求存在复制/移动构造函数,这就是为什么您只能看到int&&
中的构造函数(:
Foo f4(Foo(2));
这是来自cpp偏好的引用(不如标准,但足够接近(:
语言规则确保不发生复制/移动操作, 甚至在概念上:
在变量的初始化中,当初始值设定项表达式 是与 变量类型:
T x = T(T(T(T((((;//只调用一次 T 的默认构造函数,以初始化 x
相关文章:
- 在类构造函数中传递对外部函数的引用
- 在 c++ 中将变量作为结构构造函数中的引用传递
- C++ 尝试在不存在的构造函数中引用已删除的函数(使用 rapidJson)
- 移动构造函数和右值引用
- 为什么我的运算符 + 重载尽管是通过引用传递的,但仍调用我的复制构造函数?
- 如何使用 swig 修改类构造函数以保留对其中一个构造函数参数的引用?
- 在引用初始化中使用已删除的复制构造函数进行复制初始化
- C++:右值引用构造函数和复制省略
- 当有右值构造函数可用时,为什么从右值调用类引用构造函数重载?
- 引用构造函数时链接失败
- 为什么调用转发引用构造函数而不是复制构造函数?
- 为什么使用已删除的右值引用构造函数?
- 对 std::Optional 的转发引用构造函数的约束
- 模板是否应该为不同类型的参数制作非 Rvalue 引用构造函数/赋值
- 我是否应该对非引用构造函数参数手动调用move
- 使用左值引用错误地调用了Rvalue引用构造函数
- C++未定义的引用构造函数错误
- 调用左值引用构造函数而不是右值引用构造函数
- C++引用构造函数语法
- 不能引用构造函数的地址