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

泛型代码中处理可调用对象:优先选完美转发还是拷贝构造并移动?

优先选择完美转发的实现(transform_pf)

先看给出的两个辅助函数实现:

#include <algorithm>
#include <span>
#include <vector>

template <typename T,typename Transform>
auto transform_cm(std::span<T> spn, Transform function)
-> std::span<T> {
    std::transform(
      spn.begin(), spn.end(), 
      spn.begin(), std::move(function)
    );
    return spn;
}

template <typename T,typename Transform>
auto transform_pf(std::span<T> spn, Transform&& function)
-> std::span<T> {
    std::transform(
      spn.begin(), spn.end(), 
      spn.begin(), std::forward<Transform>(function)
    );
    return spn;
}

在泛型代码处理可调用对象时,优先选完美转发的transform_pf,理由如下:

  • 避免不必要的拷贝开销:transform_cm的参数是按值传递,无论传入左值还是右值,都会先对可调用对象做一次拷贝构造。如果可调用对象捕获了大内存的变量(比如大型std::vector),这次拷贝会带来明显的性能损耗。哪怕之后用std::move把拷贝后的对象传给std::transform,也无法消除最初拷贝的成本。

  • 保留值类别语义:transform_pf通过右值引用参数配合std::forward实现完美转发,能完全保留传入对象的原始值类别:

    • 若传入临时对象(比如匿名lambda),会以右值形式传递给std::transform,直接使用临时对象,无额外拷贝;
    • 若传入左值(比如已命名的lambda变量),会以左值引用形式传递,符合调用者可能重复使用该对象的预期。
  • 符合泛型代码的零开销原则:完美转发是C++泛型编程中实现“零抽象开销”的核心手段之一,在没有特殊限制的情况下,它能让泛型函数的行为更贴近直接调用底层函数的效率和语义。

只有当你明确需要在函数内部保留可调用对象的独立副本时,才需要考虑transform_cm这种拷贝后移动的方式。而在这个场景下,我们只是把可调用对象传递给std::transform使用,完美转发显然是更优的选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:25:09