std::move的作用和用法

一句话结论 :std::move 只是把左值无条件转换成右值引用(xvalue)的类型转换,本身不搬运任何资源;真正的移动发生在随后被选中的移动构造或移动赋值里。

标准库实现

标准库实现大致如下:

cpp 复制代码
template<class T>
constexpr std::remove_reference_t<T>&& move(T&& t) noexcept {
    return static_cast<std::remove_reference_t<T>&&>(t);
}

两个要点:

  • 它只负责"改标签",让重载决议去匹配 T&& 版本的函数。
  • 对内置类型、可平凡复制的类型(int、std::array<int,3>、std::complex 等),移动等同拷贝,没有收益。

典型用法

cpp 复制代码
// 1. 所有权转移
auto p = std::make_unique<Foo>();
auto q = std::move(p);              // p 变为 nullptr

// 2. 避免深拷贝
std::vector<std::string> v;
std::string s(4096, 'x');
v.push_back(std::move(s));          // 搬指针,不复制 4096 个字符

// 3. 右值引用参数继续转交
void sink(std::string&& s) { store(std::move(s)); }

实现移动操作时,关键是让源对象进入"可安全析构"的状态:

cpp 复制代码
class Buffer {
public:
    Buffer(Buffer&& o) noexcept
        : data_(std::exchange(o.data_, nullptr)),
          size_(std::exchange(o.size_, 0)) {}

    Buffer& operator=(Buffer&& o) noexcept {
        if (this != &o) {
            delete[] data_;
            data_ = std::exchange(o.data_, nullptr);
            size_ = std::exchange(o.size_, 0);
        }
        return *this;
    }
    // ...
};

需要注意的坑

  1. 对 const 对象 move 等于拷贝。 const string&& 绑不到 string&&,重载决议退回拷贝构造。
  2. 被移动后的对象处于"有效但未指定"状态。 只能析构或重新赋值;unique_ptr 保证为空,容器元素通常为空但不做保证。
  3. return std::move(local); 是负优化。 它阻止 NRVO。
  4. 移动构造要标 noexcept。 否则 vector 扩容时 move_if_noexcept 会退化为拷贝,因为要维持强异常保证。
  5. 泛型转发用 std::forward,不要用 std::move。 后者会无条件剥夺调用者对象,破坏左值实参。
  6. 移动裸指针不会置空源指针。 置空是 unique_ptr 等智能指针的职责,不是 std::move 的。
相关推荐
Tairitsu_H1 个月前
[C++] C++11右值引用与移动语义揭秘
开发语言·c++·c++11·右值引用·移动语义
j7~2 个月前
【C++11】C++11 新特性全套详解(列表初始化、右值引用、lambda 表达式、function 与 bind 包装器等)
c++·右值引用·lambda表达式·可变参数模板·移动语义·包装器·c++11发展史
键盘会跳舞2 个月前
C++:右值引用与移动语义源码级深度拆解——现代C++性能优化的语言基石
c++·右值引用·移动语义
shanql5 个月前
C++笔记:move语义与右值引用
右值引用·move
H Journey6 个月前
C++11 新特性 右值引用与移动语义 (Rvalue References & Move Semantics)
c++11·右值引用
量子炒饭大师7 个月前
【C++11】Cyber骇客的 亡骸剥离与右值重构 ——【右值引用 与 移动语义】(附带完整代码解析)
java·c++·重构·c++11·右值引用·移动语义
Trouvaille ~10 个月前
【C++篇】C++11新特性详解(二):右值引用与移动语义
c++·stl·基础语法·右值引用·默认成员函数·完美转发·移动语义
点云SLAM1 年前
C++ 右值引用(rvalue references)与移动语义(move semantics)深度详解
开发语言·c++·右值引用·移动语义·c++17·c+高级应用·代码性能优化
gcfer1 年前
CS144 中的C++知识积累
c++·右值引用·智能指针·optional容器