C++函数调用标识符

dim*_*mba 5 c++ c-preprocessor

请考虑以下代码:

void Foo() {
  ......
  LOG_ERROR("I'm error 1")   // call 1
  .....
  LOG_ERROR("I'm error 2")  // call 2
  .....

}
Run Code Online (Sandbox Code Playgroud)

LOG_ERROR()是一个宏.LOG_ERROR()应该打印字符串在代码中识别它,而假设代码可以改变,但A::Foo() 将保持不变.代码更改时,标识符应保留.

这可以通过添加错误代码作为参数来解决LOG_ERROR(),但我们希望从程序员中删除管理错误代码的负担.

使用__LINE__不是答案,因为Foo()可以从构建移动到构建.

因此,我想到了LOG_ERROR()相对于开始的 识别Foo():

  • 一个.通过文件名(__FILE__)+函数名称(__FUNCTION__)+ LOG_ERROR()相对于Foo()开始的行号来标识.
  • 湾 通过文件名(__FILE__)+函数名称(__FUNCTION__)+ LOG_ERROR()电话号码识别Foo().

该解决方案至少应该适用于VC++ 2008和g ++ 4.1.1.

一个建议的解决方案(链接文本)是:

#define ENABLE_LOG_ERROR static const int LOG_ERROR_start_line = __LINE__
#define LOG_ERROR(s) cerr << "error #" << (__LINE__ - LOG_ERROR_start_line) \
    << " in " << __func__ << ": " << s << endl

void Foo() {
     ENABLE_LOG_ERROR;
     //...
     LOG_ERROR("error 1");
     int i;
     LOG_ERROR("error 2");
} 
Run Code Online (Sandbox Code Playgroud)

这将迫使用户ENABLE_LOG_ERROR在每个包含的函数的开头写入, LOG_ERROR()并且有很多这样的函数.

还有其他方法可以完成任务吗?

Ben*_*mus 0

通过修改栈的思想,使用std::mapfromstd::string到count的映射,并查找函数名。

std::map<std::string, int> LOG_ERROR_count_map;
#define LOG_ERROR(s) {\
  int count = ++LOG_ERROR_count_map[ __func__ ];\
  std::cout << count << " in " __func__ ": " s << std::endl;\
}
Run Code Online (Sandbox Code Playgroud)

这意味着您不需要ENABLE_LOG_ERROR,但代价是为每个日志查找地图。(这是易用性和时间之间的权衡。)