将移动语义防止复制在这里
will move semantics prevent copying here?
// --- Move constructor
Matrix(Matrix&& other) throw() : data_(other.data_), Rows_(other.Rows_), Columns_(other.Columns_) { other.Rows_ = other.Columns_ = 0; other.data_ = nullptr; }
// --- Move assignment
Matrix & operator=(Matrix&& other) throw() {
using std::swap;
swap(Rows_, other.Rows_);
swap(Columns_, other.Columns_);
swap(data_, other.data_);
return *this; }
MultiplyAdd
实现:
template <class T>
Matrix<T> MultiplyAdd(const T a,const Matrix<T> &x,const T b) {
Matrix<T> out(a*x+b);
return out; }
template <class T>
Matrix<T> MultiplyAdd(const Matrix<T> a,const Matrix<T> &x,const T b) {
Matrix<T> out(a*x+b);
return out; }
int main(){
Matrix<> x = // some initialization
auto&& temp_auto = MultiplyAdd(a,x,b);
for (int i = 1; i < N-1; i++) {
temp_auto = MultiplyAdd(temp_auto,temp2,b); }
return 0;
}
问题:在最后的代码片段中使用auto
关键字会避免创建临时文件吗?
在最后的代码片段中使用
auto
关键字会避免临时的创建吗?
。无论如何都需要创建一个临时对象,因为temp_auto
是一个引用,并且必须有某个引用绑定到的对象。
如果你这样做的话,避免创建临时对象的几率会更高:
auto temp_auto = MultiplyAdd(a,x,b);
在这种情况下,编译器可以执行复制/移动省略,并直接将MultiplyAdd()
的结果构造为temp_auto
,而不必调用移动构造函数。
我谈论"概率"的原因是,根据c++ 11标准的12.8/31段,编译器有权,但没有义务,执行复制/移动省略。
为了澄清发生了什么,我将尝试解释当返回一个对象时编译器必须做什么。考虑这个简单的函数和随后的函数调用:
X foo() { X x; /* ... */ return x; }
// ...
X y = foo();
这里,当返回x
时,编译器必须:
- 从
x
(我们称之为t
)移出一个临时文件; 从
t
移出y
现在,由于复制省略,编译器可以避免创建临时t
,直接在y
中构造返回对象x
,并省略对move构造函数的调用。
另一方面,在循环中:
temp_auto = MultiplyAdd(temp_auto,temp2,b);
你正在做一个作业。在我们的简单示例中,这相当于:
X foo() { X x; /* ... */ return x; }
// ...
X y;
y = foo();
即使在这里,当从foo()
返回x
时,编译器必须:
- 从
foo()
(让我们再次将其称为t
)中移出x
的临时对象; - 移动
t
到y
.
即使在这种情况下,也可以通过直接将x
(而不是t
)传递给赋值给y
的移动赋值操作符来避免创建临时对象,尽管不能省略对移动赋值操作符的调用(只能省略对copy/move 构造函数的调用)。
请注意,这在您的原始示例(其中temp_auto
是引用)和在我上面修改的示例中都是正确的,其中temp_auto
是类类型的对象。
相关文章:
- 努力将整数转换为链表。不知道我在这里做错了什么
- 我可以在这里替换什么,因为我不能在 C# 中使用隐式变量的 lambda 函数?
- 当我从下面的代码中删除关键字 virtual 时,它可以正常工作,否则会出现错误。在这里"virtual"字的意义是什么?
- File.cpp.o:OpenPose 标志 CMakeFiles/.. 的多重定义/main.cpp.o:首先在这里定
- 为什么thread_local变量在这里从未初始化?
- 为什么我必须在这里使用dynamic_cast
- 在这里,当我们比较 if(vc[i]==vc1[i]) 时,它是向量数组. 实际上比较的值是多少,
- 我正在尝试使用 while 循环从字符串中删除字母,直到没有字母。我在这里做错了什么?
- 为什么 C++20 中的 [[可能]] 属性在这里引发警告?
- 我在这里正确传递参数了吗?
- 为什么gmp会在这里与"invalid next size"重新定位一起崩溃?
- 复制交换习惯用法-我们可以在这里使用动态强制转换操作吗
- 为什么在这里称为复制构造函数
- 为什么我在这里调用构造函数和复制构造函数
- 新手编码器在这里: C++ 使用函数将向量复制到数组中
- 为什么在这里调用复制构造函数而不是普通的构造函数和重载赋值运算符
- C++11:为什么在这里调用复制ctor
- 为什么我需要在这里复制构造函数
- 将移动语义防止复制在这里
- 为什么在这里调用复制构造函数