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
相关产品推荐
相关产品推荐

