c++ - 什么时候需要显式调用 std::move ,什么时候不需要在 cpp 中?

标签 c++ c++11 move-constructor

我正在学习 Stroustrup 的“C++ v2 之旅”。这当然不是一本 C++ 初学者的书,但很有趣。
我有一个谷歌并浏览了SO,但对此并不满意。
现在,我想我明白编译器何时可以使用移动构造函数,但显然我不明白。在这里,我展示了移动构造函数和我认为会使用它的函数。它没有。仅当我明确使用 std::move 时。为什么是这样?我的理解是本地 r 将在返回时隐式“移动”。

template<typename T>
Vector<T>::Vector(Vector<T> && a) // move constructor
     :elem{a.elem},sz{a.sz}{
     a.elem=nullptr;
     a.sz=0;
}

template<typename T>
Vector<T> moveVectorAfterAdd(const Vector<T> &  v1, const Vector<T> & v2){
     Vector<T> r =   v1+v2;
     return std::move(r);
     //return r;
}

int main(void) {
     Vector<double> v1(1);
     Vector<double> v2=v1;
     Vector<double> v3=v2;

     Vector<double> v4=moveVectorAfterAdd(v1,v2);

     return 0;
}
(作为旁注,如果我实际上不使用 std::move,即使在没有优化的情况下编译,lldb 也不会让我在移动构造函数中设置断点。)
很高兴收到任何和所有澄清!

最佳答案

When do you need to explicitly call std::move and when not in cpp?


简而言之,技术上精确的话:当您有一个想要成为右值的左值时,请使用 std::move 。更实际的是:当您想要一个拷贝而不是移动时,您会想要这样做。因此名称为 std::move。
在示例中,您返回一个自动变量。使用 std::move 无法避免复制,因为在返回自动变量的特殊情况下,即使是左值也会发生移动。

Here I show the move constructor and the function that I thought would use it. It doesn't.


仅仅因为在抽象机器中有一个移动,并不一定意味着会有对移动构造函数的调用。这是一件好事,因为什么都不做可能比调用移动构造函数更快。
这称为(命名)返回值优化。或者更普遍的复制省略。使用 std::move 会抑制这种优化,因此在这种情况下不仅没有必要,而且还会适得其反。

关于c++ - 什么时候需要显式调用 std::move ,什么时候不需要在 cpp 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69114044/

相关文章:

c++ - 打开不存在的文件时如何使 ofstream 构造函数失败?

c++ - Qt - Visual Studio 2010 的 Ui 访问冲突

c++ - {0, 0} 会初始化结构中的数组吗?

c++ - 如何检测一个容器是否保证有序列存储

c++ - 默认情况下应调用 move 构造函数

移动所有者时,对所有者的 C++ 复合引用已损坏

c++ - 删除元组成员的复制构造函数导致错误

c++ - 如何创建具有 N 种不同类型的变量成员的模板类,以便

c++ - 当被调用方法使用调用者已经锁定的相同锁时,如何避免死锁?

随机数生成器的 C++11 线程安全