You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确使用std::move将参数移入C++类构造函数?

如何用最少拷贝将std::vector传入类中

先看基础场景代码:

class MyClass 
{
public:
    MyClass(std::vector<int> v)
        : m_vector(v) {}

    void doSomething();

private:
    std::vector<int> m_vector;
};

int main() 
{
    std::vector<int> myVector;
    // ...
    // 处理myVector
    // ...
    
    MyClass myItem(myVector);
    myItem.doSomething();
}

显然把vector移动到MyClass比拷贝高效,但不确定构造函数怎么写、参数怎么传。以下几个可编译版本里,哪个能保证最少拷贝?


版本A分析

MyClass(const std::vector<int>& v)
    : m_vector(std::move(v)) {}

MyClass myItem(myVector);
  • v是const左值引用,std::move(v)得到的是const右值引用,而std::vector的移动构造函数只接受非const右值引用,所以这里实际会调用拷贝构造函数初始化m_vector
  • 总拷贝次数:1次

版本B分析

MyClass(std::vector<int> v)
    : m_vector(std::move(v)) {}

MyClass myItem(myVector);
  • 第一步:传递左值myVector给形参v,调用拷贝构造函数创建v
  • 第二步:std::move(v)将v移动到m_vector,调用移动构造(无拷贝)
  • 总拷贝次数:1次

版本C分析

MyClass(const std::vector<int>& v)
    : m_vector(v) {}

MyClass myItem(std::move(myVector));
  • 形参v绑定到std::move(myVector)的右值,但因为是const引用,初始化m_vector时直接拷贝v的内容
  • 总拷贝次数:1次

版本D分析

MyClass(const std::vector<int>& v)
    : m_vector(std::move(v)) {}

MyClass myItem(std::move(myVector));
  • 同样,v是const引用,std::move(v)无法触发移动构造,m_vector还是通过拷贝构造初始化
  • 总拷贝次数:1次

版本E分析

MyClass(std::vector<int>&& v)
    : m_vector(std::move(v)) {}

MyClass myItem(std::move(myVector));
  • 第一步:std::move(myVector)把左值转为右值,匹配构造函数的右值引用形参v,这一步无拷贝(只是引用传递)
  • 第二步:std::move(v)将v移动到m_vector,调用移动构造(无拷贝)
  • 总拷贝次数:0次,是所有版本里效率最高的

最优实践

如果要同时支持**传入左值(必须拷贝)和传入右值(可以移动)**的场景,推荐提供两个构造函数:

// 处理左值,执行拷贝
MyClass(const std::vector<int>& v)
    : m_vector(v) {}

// 处理右值,执行移动
MyClass(std::vector<int>&& v)
    : m_vector(std::move(v)) {}

或者用C++11及以上的万能引用+完美转发,更简洁地覆盖所有情况:

template<typename T>
MyClass(T&& v)
    : m_vector(std::forward<T>(v)) {}

这样不管传入左值还是右值,都会自动选择最优的构造方式,彻底避免不必要的拷贝。

内容的提问来源于stack exchange,提问作者Michele Spagnolo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 20:33:25