实现一个登录函数或宏可以记录日期和函数名

Posted

技术标签:

【中文标题】实现一个登录函数或宏可以记录日期和函数名【英文标题】:implement a loggin function or macro can log date and function name 【发布时间】:2015-07-10 07:19:21 【问题描述】:

我想编写一个日志函数或宏,它可以接受其他回调函数作为参数并在内部运行回调函数,记录运行时和名称。 但是回调函数可能有不同的参数类型和数量,我不想将回调函数的名称作为参数显式传递。

我尝试使用 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"));

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

【问题讨论】:

您是否查看过可变参数模板(C++11 起),例如eli.thegreenplace.net/2014/variadic-templates-in-c 这不是C...删除它。 【参考方案1】:

编译时会丢失函数(和变量等)的名称。编译器(真的)不知道函数的名称。您可以使用__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)

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

【讨论】:

这是怎么发生的?我们几乎在同一时间得到了相同的答案:-) 谢谢,它有效。顺便说一下,如果回调函数有不同的返回类型,如何传入和处理返回 @Amit:不时发生 - 为变量等选择明显的名称,这与它非常相似有关。 std::function&lt;void()&gt; 可以接受返回非void 的可调用对象,所以第一个解决方案是可以的。此外,使用模板函数,我们必须传递std::function 或显式提供RET,因为对于某些可调用(如lambda)无法推断出RET @MatsPetersson模板函数返回类型无法推断,调用log(callbackFunc, 1)error【参考方案2】:

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

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

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


log(callbackFunc1, 1);

【讨论】:

以上是关于实现一个登录函数或宏可以记录日期和函数名的主要内容,如果未能解决你的问题,请参考以下文章

如何将 printf() 包装到函数或宏中?

Mysql常见函数-字符函数-数序函数-日期函数-日期函数- 流程控制函数--分组函数

单行函数

雪花中的 Javascript 函数将表名附加到当前日期

在C语言中,调用函数除函数名外,还必须有()。

Hive函数用法:Cast(字段名 as 转换的类型 )