将调用者__FILE__ __LINE__传递给函数而不使用宏

Nic*_*oni 22 c++ c-preprocessor

我习惯了这个:

class Db {
  _Commit(char *file, int line) {
    Log("Commit called from %s:%d", file, line);
  }
};

#define Commit() _Commit(__FILE__, __LINE__)
Run Code Online (Sandbox Code Playgroud)

但最大的问题是我重新定义了Commit全局这个词,而在一个400k行的应用程序框架中,这是一个问题.而且我不想使用像这样的特定词DbCommit:我不喜欢冗余db->DbCommit(),或者在任何地方手动传递值:db->Commit(__FILE__, __LINE__)最糟糕的.

那么,有什么建议吗?

Joh*_*ing 50

所以,你正在寻找使用文件和行信息进行日志记录(或其他东西),而你宁愿不使用宏,对吧?

在一天结束时,它根本无法在C++中完成.无论你选择什么机制 - 内联函数,模板,默认参数或其他东西 - 如果你不使用宏,你最终会得到日志函数的文件名和亚麻,而不是呼叫点.

使用宏.这是一个真正无法更换的地方.

编辑:

即使是C++常见问题解答说宏有时也是两个邪恶中的较小者.

EDIT2:

正如Nathon在下面的评论中所说,在你使用宏的情况下,最好明确一下.给你的宏宏名称,COMMIT()而不是Commit().这将使维护人员和调试人员清楚地知道正在进行宏调用,并且在大多数情况下它应该有助于避免冲突.两件好事.

  • 您可能必须使用宏,但这并不意味着您无法明确它.`COMMIT()`显然是一个宏调用(通过常规约定),因此不应该与400kloc应用程序框架中的任何内容冲突. (11认同)
  • @Nocola:通过让用户知道它是一个宏而不是一个函数来提高可读性**.否则,他们可能会尝试在没有意义的地方使用宏(例如尝试创建指向它的函数指针)( (8认同)
  • +1 - 我无法相信我正在回答说"使用宏",但无论如何都要+1. (3认同)
  • @Nicola在宏的情况下,你想喊"这是一个宏".宏本质上是危险的,应该标记为这样. (2认同)

小智 6

等到C++20,你可以使用source_location

https://en.cppreference.com/w/cpp/utility/source_location