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

C++折叠表达式实现同步打印模板出现不必要参数拷贝如何解决

修改方案

造成参数拷贝的核心原因是原代码中所有可变参数都是按值传递,传入自定义类型时会触发拷贝构造。我们可以通过转发引用+完美转发的方式避免拷贝,同时可以用C++17折叠表达式简化原有递归实现:

核心修改点

  • 所有可变参数接收改为转发引用语法Args&&... args,避免值传递的隐式拷贝
  • 参数传递过程中使用std::forward<Args>(args)完美转发,保留参数原本的引用属性和值类型
  • 新增<utility>头文件引用,提供std::forward的实现

修改后完整代码

#include <iostream>
#include <string>
#include <sstream>
#include <mutex>
#include <Windows.h>
#include <utility> // 新增:提供std::forward实现

std::mutex sync_mutex;

template <typename... Args>
void sync_print(Args&&... args) // 改为转发引用接收参数
{
    std::ostringstream s;
    // 折叠表达式直接实现参数写入,不需要额外递归impl函数
    (..., (s << std::forward<Args>(args) << " "));

    {
        std::lock_guard<std::mutex> lg(sync_mutex);
        std::cout << s.str() << std::endl;
    }
}

如果你需要保留原有两层impl的实现结构,也可以按如下方式修改:

#include <utility>

std::mutex sync_mutex;

template<typename T>
void sync_print_impl(std::ostringstream& str, T&& t) // 转发引用接收单个参数
{
    str << std::forward<T>(t) << " ";
}

template<typename ... Args>
void sync_print_impl(std::ostringstream& str, Args&& ... args) // 转发引用接收可变参数
{
    str;
    (..., sync_print_impl(str, std::forward<Args>(args))); // 完美转发参数
}

template <typename... Args>
void sync_print(Args&&... args) // 转发引用接收入口参数
{
    std::ostringstream s;
    sync_print_impl(s, std::forward<Args>(args)...);

    {
        std::lock_guard<std::mutex> lg(sync_mutex);
        std::cout << s.str() << std::endl;
    }
}

效果验证

修改后运行test2测试用例,OutputDebugString的输出将不再出现copy constructor日志,仅保留原对象的构造和析构日志:

test_class
~test_class

完全避免了不必要的参数拷贝,原有打印功能完全不受影响。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 01:42:01