C++14中如何在满足条件时延迟实例化函数的函子参数?
解决方案
要实现仅在条件满足时才延迟实例化error_logger,核心思路是传递工厂函数而非直接传递已构造的函子——只有当触发条件为真时,才调用工厂生成实际的日志函子。以下是具体实现方式:
1. 修改HandleError函数为模板版本
利用C++14的模板推导特性,让函数接收任意可调用的工厂类型,避免std::function的额外类型擦除开销:
template <typename ErrorLoggerFactory> void HandleError(int err_code, ErrorLoggerFactory error_logger_factory) { // ... 原有错误处理逻辑 if (condition) { // 仅当条件满足时,才生成日志函子并调用 auto error_logger = error_logger_factory(); error_logger(); } // ... 后续逻辑 }
2. 调用端传递延迟构造的工厂
调用时不再直接传日志lambda,而是传一个返回日志lambda的工厂lambda,这样只有当condition为真时,内层的日志函子才会被实例化:
// 示例:捕获大对象时,延迟构造避免不必要的拷贝 LargeObject big_data; HandleError(err_code, [&big_data](){ // 这部分代码仅在condition为真时才会执行,big_data的捕获也延迟到此时 return [big_data](){ std::cout << "Error: " << err_code << ", data: " << big_data.toString() << std::endl; }; });
3. 借助Boost简化(可选)
如果想用Boost库进一步封装工厂逻辑,可以使用boost::lazy来包装日志逻辑,让调用更简洁:
#include <boost/lazy.hpp> void HandleError(int err_code, boost::lazy<void()> error_logger_lazy) { if (condition) { // 触发延迟求值 error_logger_lazy(); } } // 调用方式更简洁 HandleError(err_code, boost::lazy([](){ std::cout << "Error logged" << std::endl; }));
原方案的问题
原代码中,调用者必须提前构造std::function(包括lambda的捕获操作),即使condition为假,这些构造、拷贝/移动的开销都白白浪费了——尤其当lambda捕获大对象、或者构造函子本身代价较高时,这种浪费会更明显。
内容的提问来源于stack exchange,提问作者Christophe
相关产品推荐
相关产品推荐

