这可能与其他问题非常相似;我环顾四周,但我不知道我说的是什么,以确保。
我正在编写一个“应该”就地的功能,但这是通过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
的有效用途,还是我在某种程度上打破了“复制省略”(或者由于其他原因而不好)?
编辑:请求CallBLASDgemm的签名;它是
CallBLASdgemm(const ArrayClass& U, const TransformMatrix* M,
ArrayClass& V);
答案 0 :(得分:2)
是的,这是一个有效的用例。如果您有一个命名临时(左值),将其移至U
的唯一方法是使用std::move
将其转换为右值。
我认为你担心的是人们做return std::move(object);
的时候。这是一种悲观,因为在大多数情况下,可以省略将对象复制到返回值中。
答案 1 :(得分:2)
在这种情况下,无论是否使用复制省略都不会执行复制,因此已经无法解决问题。因为U_temp
是左值,所以如果你这样做,编译器必须调用拷贝构造函数:
U = U_temp;
但是,您知道U_temp
不再被使用,因此移除其值是完全安全的,并且可能更快(即,如果ArrayClass
实现了移动赋值构造函数)。在这里使用std::move
很好,甚至鼓励。
答案 2 :(得分:1)
这是有效的。但是,我要做的是:
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
。