c++ - 有没有办法在c ++中没有宏来获取行号?
问题描述
我正在编写一个记录器,我希望记录器还记录调用它的行、函数和文件。我已经尝试过#define my_logger(format, ...) _log(format, __LINE__, __PRETTY_FUNCTION__, __FILE__, __VA_ARGS__)
,但是,这给我带来了几个问题(我不能轻易地重载它,我不能把它放在一个命名空间中,而不是最便携的等等)。
有没有一种方法可以让我声明一个普通函数,void my_logger(const char* format, ...)
并且在函数定义中让它知道调用它的行,__LINE_FUNCTION_WAS_CALLED_FROM__
如果存在这样的宏?至少它需要在 GCC 上工作,并且真的应该是跨平台的。
编辑:跨平台,我只指 x86 和 ARM 上的 Linux 和 Windows
解决方案
不能有这样的宏__LINE_FUNCTION_WAS_CALLED_FROM__
。没有办法奏效。
从 C++20 开始,有一种方法可以通过传递默认的 initialized 将行、函数等转换为普通函数std::source_location
:
void log(std::string_view message,
std::source_location location = std::source_location::current());
但是,由于它依赖于默认参数,因此可变参数实现起来有点棘手:How to use source_location in a variadic template function?
在 C++20 之前,宏是您唯一的可移植选项。
我看到你调用了一个_log
在你的宏中命名的函数。该标识符保留给全局命名空间中的语言实现。您可能应该为该函数指定另一个名称以避免未定义的行为。
log
也保留在全局命名空间中。无论如何,您都应该在自定义命名空间中声明所有名称(自然而然的自定义命名空间除外)。
[宏是] ...不是最便携的
如果您要替换__PRETTY_FUNCTION__
为__func__
,则该宏将可移植到所有符合标准的编译器 - 尽管由 给出的确切字符串__func__
可能因实现而异。
推荐阅读
- ruby - Rspec Instance Double Received Unexpected Message
- javascript - 找不到模块“提示同步”
- python - PULSE on github(提供链接) RuntimeError: CUDA out of memory....阻止程序“run.py”执行
- javascript - 控制台日志 ({value}) 与 console.log(value) 不同
- java - sun.net.www.protocol.file 将代码从 1.6 jdk 迁移到 11 jdk 问题
- c# - 使用 Navigation.PushAsync 加载新页面时退出提示不起作用
- swift - 将字符串时间快速转换为日期
- json - Spark将文件读入数据框
- jenkins - 将 SonarQube 与詹金斯集成
- c - 将结构传递给 Cosmic 编译器和 STM8 中的函数时出现“无效的间接操作数”错误