C++中直接传递函数返回值与先存变量再传参的区别及最优方案
C++两种参数传递写法的差异分析
1. 语义与生命周期差异
- 第一种写法
function1(function2());:function2的返回值是临时对象,生命周期仅维持在整个函数调用表达式执行期间,表达式执行完成后临时对象会被自动销毁。 - 第二种写法:
var1 = function2(); function1(var1);
function2 的返回值会先赋值给局部变量var1,var1的生命周期会持续到它所在的作用域结束,除非主动销毁。
2. 运行效率对比
这是两种写法差异最大的维度,性能差距和C++版本、返回值类型强相关:
C++11之前(无移动语义)
第一种写法性能明显更优:编译器可以触发返回值优化(RVO/NRVO),直接将function2返回的对象构造在function1的形参内存空间中,完全省去额外的拷贝开销。
而第二种写法需要先把function2的返回值拷贝构造到var1,再把var1拷贝给function1的形参,多了两次拷贝操作,当返回值是占用内存较大的自定义类型(比如大数组、复杂容器)时,开销差距会非常明显。
C++11及之后(支持移动语义)
第一种写法仍然是更优的选择:
- 如果返回值是支持移动构造的类型,第二种写法的拷贝开销会被降低为移动开销,但第一种写法连移动操作都可以省去,开销更低。
- 如果返回值是不支持移动的类型(比如小体积POD类型、未实现移动构造的自定义类型),第二种写法仍然会产生额外的拷贝开销。
- 额外注意:如果
function1的形参是值传递类型,第二种写法传入的var1是左值,默认会触发拷贝构造,除非显式调用std::move(var1)转为右值,而第一种写法传入的临时对象本身就是右值,会自动触发移动构造,无需额外处理。
3. 可调试性与可读性差异
- 第一种写法的优势是逻辑紧凑,没有冗余的中间变量,不需要读者额外关注中间变量的后续用途,适合不需要复用返回值的场景。劣势是不方便调试,很难直接查看
function2的返回结果,打断点、加日志都需要修改代码拆分变量。 - 第二种写法的优势是方便调试,可以直接查看、打印
var1的值,排查问题更方便,同时如果返回值后续还要复用,也只能选择第二种写法。劣势是多了一个不必要的中间变量,如果后续没有使用var1,会让读者疑惑是不是漏了逻辑,降低代码可读性。
最优选择结论
没有绝对的最优方案,需要结合场景判断:
- 如果
function2的返回值不需要在function1调用之后复用,优先选择第一种写法,性能更高、逻辑更紧凑。 - 如果需要调试查看返回值、或者返回值需要后续多次使用,选择第二种写法更合适。
内容的提问来源于stack exchange,提问作者user15747807
相关产品推荐
相关产品推荐

