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

如何实现C++调用器函数:接收函数与可变参数并执行

解决方案

你要实现的是一个通用函数调用包装器,同时集成调试日志能力。原代码的问题在于用void*存储函数指针无法安全调用,C风格可变参数...也没法适配不同函数的参数签名,以下是可行的实现方案:

1. 核心实现:模板+可变参数模板

利用C++的模板和可变参数特性,能完美适配任意签名的函数与参数:

#include <iostream>
#include <utility>

// 调试开关:可用全局变量或编译宏控制
bool g_debug_enabled = true;

template<typename Func, typename... Args>
auto caller(Func func, Args&&... args) -> decltype(func(std::forward<Args>(args)...)) {
    // 调试模式下输出自定义信息
    if (g_debug_enabled) {
        std::cout << "[DEBUG] 执行函数,参数数量:" << sizeof...(Args) << std::endl;
        // 可扩展输出参数具体值、调用位置等信息
    }

    // 调用目标函数,完美转发参数避免不必要拷贝
    return func(std::forward<Args>(args)...);
}

2. 使用示例

// 测试函数1:无参无返回值
void print_hello() {
    std::cout << "Hello World" << std::endl;
}

// 测试函数2:带参有返回值
int calculate_sum(int a, int b) {
    std::cout << "计算a+b:" << a << "+" << b << std::endl;
    return a + b;
}

int main() {
    // 开启调试模式
    caller(print_hello);
    int sum = caller(calculate_sum, 15, 25);
    std::cout << "计算结果:" << sum << std::endl;

    // 关闭调试模式
    g_debug_enabled = false;
    caller(print_hello);
    return 0;
}

3. 关键细节说明

  • 完美转发:std::forward<Args>(args)...保证参数的左值/右值属性被正确传递,避免性能损耗。
  • 返回值兼容:decltype(func(std::forward<Args>(args)...))自动推导目标函数的返回值类型,不管是void还是其他类型都能适配。
  • 调试信息扩展:如果需要输出函数名或调用位置,可以结合C++20的std::source_location获取更详细的调试上下文。

4. 编译期控制调试开关(可选)

如果希望调试代码在发布版本中完全移除,可改用编译宏:

#define DEBUG_MODE 1

template<typename Func, typename... Args>
auto caller(Func func, Args&&... args) -> decltype(func(std::forward<Args>(args)...)) {
#if DEBUG_MODE
    std::cout << "[DEBUG] 执行函数..." << std::endl;
#endif
    return func(std::forward<Args>(args)...);
}

编译时通过-DDEBUG_MODE=0关闭调试代码,发布版本不会包含任何调试相关逻辑,无性能影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 23:03:11