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

函数实参传递:右值引用与const左值引用的效率对比

关于两种字符串传递方式的效率分析

咱们先把这个问题拆开来聊,首先得纠正一个容易混淆的点,再一步步分析效率差异:

1. 先澄清参数传递阶段的误区

你提到的「拷贝构造/移动构造」其实不会发生在参数传递这一步,咱们具体看:

  • 对于processString1(const string & str):传入字符串字面量"Hello"时,编译器会先临时构造一个std::string对象(从const char*字面量转换而来),然后这个临时对象直接绑定到const string&引用上——引用只是给已有对象起别名,不需要创建新字符串,所以这一步没有拷贝/移动开销。
  • 对于processString2(string && str):同样,编译器先构造临时std::string对象,再把这个临时右值绑定到string&&引用上——还是单纯的绑定操作,没有拷贝或移动构造。

2. 真正体现效率差的场景:函数内部需要保存字符串副本

你说的拷贝/移动构造,应该是指函数内部要把传入的字符串存为本地副本的情况,比如:

// processString1 内部保存副本
void processString1(const string & str) {
    string internal_str = str; // 这里调用拷贝构造函数
}

// processString2 内部保存副本
void processString2(string && str) {
    string internal_str = std::move(str); // 这里调用移动构造函数
}

这时候差异就非常显著了:

  • 拷贝构造:std::string的拷贝构造需要重新分配内存,把原字符串的所有字符逐一复制,时间复杂度是O(n)(n为字符串长度),内存开销大。
  • 移动构造:std::string的移动构造只是把原对象内部的字符数组指针、长度、容量等成员直接“转移”给新对象,原对象变为空状态,整个过程是O(1)的常数时间,几乎没有开销。

3. 最终结论

  • 如果函数只是读取传入的字符串,不需要保存副本:两种传递方式效率几乎无差别,都是绑定临时对象,没有额外开销。
  • 如果函数需要保存传入字符串的副本:processString2这种右值引用配合移动构造的方式,效率远高于processString1的左值引用+拷贝构造。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 07:19:04