如何实现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
相关产品推荐
相关产品推荐

