std::move 对于 "in-place operation"
std::move for "in-place operation"
这可能与其他问题非常相似;我环顾四周,但我不知道我在说什么,足以确定。
我正在编写一个 "should" 就地函数,但它是通过 BLAS 调用实现的。 BLAS 调用不在位,所以我需要做一个临时的。因此:
void InPlace(ArrayClass& U, const TransformMatrix* M){
ArrayClass U_temp;
CallBLASdgemm(U, M, U_temp); //Now U_temp contains the correct output.
U = std::move(U_temp);
}
这是对 std::move
的有效使用,还是我以某种方式破坏了 "copy elision"(或者由于其他原因它不好)?
编辑:已请求 CallBLASDgemm 的签名;这是
CallBLASdgemm(const ArrayClass& U, const TransformMatrix* M,
ArrayClass& V);
是的,这是一个有效的用例。如果你有一个命名的临时(左值)将它移动到 U
的唯一方法是使用 std::move
将它转换为右值。
我想你担心的是人们什么时候做 return std::move(object);
。这是一种悲观情绪,因为在大多数情况下,可以省略 return 值中的对象副本。
在这种情况下,无论有没有复制省略,都不会执行任何复制,所以这已经不可能了。因为 U_temp
是一个左值,如果你这样做,编译器必须调用复制构造函数:
U = U_temp;
但是,您知道 U_temp
不会再被使用,因此移走它的值是完全安全的并且可能更快(也就是说,如果 ArrayClass
实现了一个移动赋值构造函数).在这里使用 std::move
很好,甚至值得鼓励。
这是有效的。但是,我要做的是:
ArrayClass myCallBLASdgemm(const ArrayClass& U, const TransformMatrix* M) {
ArrayClass tmp;
CallBLASdgemm(U, M, tmp);
return tmp; // elided move
}
void InPlace(ArrayClass& U, const TransformMatrix* M){
U = myCallBLASdgemm(U, M);
}
它运行相同的代码,但没有在外部范围内看到临时文件。
事实上,myCallBLASdgemm
非常干净,您可以删除 InPlace
并在需要的地方调用 myClassBLASdgemm
。
这可能与其他问题非常相似;我环顾四周,但我不知道我在说什么,足以确定。
我正在编写一个 "should" 就地函数,但它是通过 BLAS 调用实现的。 BLAS 调用不在位,所以我需要做一个临时的。因此:
void InPlace(ArrayClass& U, const TransformMatrix* M){
ArrayClass U_temp;
CallBLASdgemm(U, M, U_temp); //Now U_temp contains the correct output.
U = std::move(U_temp);
}
这是对 std::move
的有效使用,还是我以某种方式破坏了 "copy elision"(或者由于其他原因它不好)?
编辑:已请求 CallBLASDgemm 的签名;这是
CallBLASdgemm(const ArrayClass& U, const TransformMatrix* M,
ArrayClass& V);
是的,这是一个有效的用例。如果你有一个命名的临时(左值)将它移动到 U
的唯一方法是使用 std::move
将它转换为右值。
我想你担心的是人们什么时候做 return std::move(object);
。这是一种悲观情绪,因为在大多数情况下,可以省略 return 值中的对象副本。
在这种情况下,无论有没有复制省略,都不会执行任何复制,所以这已经不可能了。因为 U_temp
是一个左值,如果你这样做,编译器必须调用复制构造函数:
U = U_temp;
但是,您知道 U_temp
不会再被使用,因此移走它的值是完全安全的并且可能更快(也就是说,如果 ArrayClass
实现了一个移动赋值构造函数).在这里使用 std::move
很好,甚至值得鼓励。
这是有效的。但是,我要做的是:
ArrayClass myCallBLASdgemm(const ArrayClass& U, const TransformMatrix* M) {
ArrayClass tmp;
CallBLASdgemm(U, M, tmp);
return tmp; // elided move
}
void InPlace(ArrayClass& U, const TransformMatrix* M){
U = myCallBLASdgemm(U, M);
}
它运行相同的代码,但没有在外部范围内看到临时文件。
事实上,myCallBLASdgemm
非常干净,您可以删除 InPlace
并在需要的地方调用 myClassBLASdgemm
。