实现loggin函数或宏可以记录日期和函数名称

时间:2015-07-10 07:19:21

标签: c++ c++11 macros

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

我尝试使用std :: bind和std :: function

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"));

另外,也许回调函数有不同的返回类型,可以实现这样的日志函数吗?

2 个答案:

答案 0 :(得分: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)

(我还没有测试过这个,但我相信它会起作用)

答案 1 :(得分:0)

您可以将日志调用包装在可变参数宏中(正如您所猜测的那样#34;)以获取参数本身(函数地址)及其名称:

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

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

log(callbackFunc1, 1);