标准::移动"in-place operation"

std::move for "in-place operation"

本文关键字:in-place operation 移动 标准      更新时间:2023-10-16

这可能与其他问题非常相似;我环顾四周,但我不知道我在说什么,可以确定。

我正在编写一个"应该"就地的函数,但它是由 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);
在这种情况下,

不会执行带有或不带有复制省略的副本,因此这已经是不可能的了。因为U_temp是一个左值,编译器必须调用复制构造函数,如果你这样做:

U = U_temp;

但是,您知道U_temp将不再使用,因此移开其值是完全安全的,并且可能会更快(也就是说,如果ArrayClass实现了移动赋值构造函数(。在这里使用std::move很好,甚至鼓励这样做。

是的,这是一个有效的用例。 如果您有命名的临时(左值(,将其移动到U的唯一方法是使用 std::move 将其转换为右值。

我认为你担心的是人们什么时候做return std::move(object);. 这是一种悲观,因为在大多数情况下可以省略返回值中的对象副本。

这是

有效的。 但是,我要做的是:

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