C++中如何获取被调用函数名称而非调用者函数名称
解决方案
要获取传入函数的名称,核心问题在于函数指针/可调用对象本身不携带编译期的名称信息,__func__宏只能返回当前函数(即LogCalledFunction)的名称,因此必须在调用点通过宏捕获目标函数的名称,再传递给日志函数。
实现步骤
- 调整日志函数,增加参数接收函数名称字符串:
#include <iostream> #include <functional> // 全局调试控制变量 bool g_debugEnabled = true; template <typename F, typename... Args> void LogCalledFunction(const char* funcName, F f, Args... args) { if (g_debugEnabled) { std::cout << "Called function: " << funcName << std::endl; } std::invoke(f, args...); }
- 定义宏自动捕获函数名称并调用日志函数:
// 宏用于自动字符串化函数名,兼容无参数调用场景 #define LOG_CALL(func, ...) LogCalledFunction(#func, func, ##__VA_ARGS__)
使用示例
- 调用普通函数:
void MyNormalFunction(int a, const std::string& b) { std::cout << "Executing MyNormalFunction: " << a << ", " << b << std::endl; } int main() { LOG_CALL(MyNormalFunction, 123, "test"); return 0; }
- 调用类成员函数:
class MyClass { public: void MyMemberFunction(double x) { std::cout << "Executing MyMemberFunction: " << x << std::endl; } }; int main() { MyClass obj; LOG_CALL(&MyClass::MyMemberFunction, &obj, 3.14); return 0; }
关键说明
#func是预处理器的字符串化操作符,会将传入的函数名(包括成员函数的限定名)转换为字符串字面量,编译期完成处理,无运行时性能损耗。##__VA_ARGS__用于处理无参数调用场景,避免出现多余逗号导致的编译错误。- 对于lambda表达式,
#func会输出operator()(lambda的默认调用操作符名称),若需要更友好的标识,可手动传递自定义名称,例如:LogCalledFunction("MyDebugLambda", [](){/* lambda逻辑 */})。
内容的提问来源于stack exchange,提问作者user17096148
相关产品推荐
相关产品推荐

