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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 19:10:08