2015-07-10 69 views
1

我想写一个日志函数或宏,它可以接受其他回调函数作为参数,并在里面运行回调函数,记录运行时和名称。 但回调函数可能有不同的参数类型和数量,我不想明确地将回调函数名作为参数传递。实现一个登录函数或宏可以登录日期和函数名

我尝试使用std ::绑定和std ::功能

void log(std::function<void()> callbackFunc){ 
     //assuming all callbackFunc return type is void 
     struct timeval tmBegin, tmEnd; 
     gettimeofday(&tmBegin); 
     callbackFunc(); 
     gettimeofday(&tmEnd); 
     //then write tmEnd - tmBegin to file 
     //but i dont know how to get callbackFunc's name} 

void callbackFunc1(int); 
void callbackFunc2(int ,char, string); 
log(std::bind(callbackFunc1, 1)); 
log(std::bind(callbackFunc2, 2, 'c', "test")); 

除此之外,也许回调函数具有不同的返回类型,可以实现这样的日志功能?

+1

你有没有看着可变参数模板(因为C++ 11),例如在http://eli.thegreenplace.net/ 2014/variadic-templates-in-c/ – jensa

+0

这不是'C' ...将其删除。 –

回答

2

的函数的名称(和变量等等)编译时会丢失。编译器没有(真的)知道函数的名字。您可以使用__FUNCTION__来获取您所在功能的名称,但在这种情况下无效。你也许可以用一个代替bind的宏来做些什么,或者简单的解决方法是只传递一个字符串和作为log的参数的函数。

宏解决方案更复杂,因为你必须处理变量参数,但像这样的工作):

#define LOG(f, ...) log(std::bind(f, __VA_ARGS__), #f) 

和修改log到:

void log(std::function<void()> callbackFunc, const char* name) 

编辑:不同返回类型可以通过使log为模板化函数来处理,并使用模板作为std::function返回类型中的类型参数:

template<typename RET> 
void log(std::function<RET()> callbackFunc) 

(我没有测试过这一点,但我相信它会工作)

+0

这是怎么发生的?我们有几乎相同的答案,在同一时间:-) – Amit

+0

谢谢,它的工作原理。顺便说一句,如果回调函数具有不同的返回类型,如何传入并处理返回 – cavehubiao

+0

@Amit:时常发生 - 为变量等选择显而易见的名称将与它非常相似。 –

0

你可以换一个可变参数宏日志调用(如你“猜”)抢参数本身(函数地址),以及它的名字:

#define log(f, ...) _log(std::bind(f, __VA_ARGS__), #f) 

void _log(std::function<void()> callbackFunc, const char *fName){ 
    // ... 
} 

log(callbackFunc1, 1);