在我目前的项目中,我使用了:
Log(__LINE__, __FUNCTION__, message);
但是新的C++20实用程序类std::source_location
附带了函数line()
、column()
、file_name()
和function_name()
,它们做同样的事情。因此,新的C++20方式将是:
log(std::string message,const std::source_location& location = std::source_location::current())
{
std::cout << "Debug:"
<< location.file_name() << ':'
<< location.line() << ' '
<< message << '\n';
}
与旧的标准双下划线宏__LINE__
、__FILE__
、__func__
相比,新的__func__
有什么优势呢?这些宏已经成为标准C++很长时间了。
我正在尝试确定是否有足够的优势来证明修改我当前项目中的代码以优先使用新的std::source_location
对象而不是宏。
发布于 2021-06-14 20:20:13
在C++20之前,你必须在冗长(手动将__LINE__
、__FILE__
、__func__
传递给每个调用)和使用宏为你完成这两个操作之间做出选择。
std::source_location
为您提供了一个很好的调用语法,而不需要宏。没有其他隐藏的优势。
发布于 2021-06-14 21:55:04
你的例子是我能想到的最好的动力。在过去,__LINE__
和_FILE__
是使用宏作为调试日志的最佳借口。现在,这不再适用了。
在过去,你基本上有两个选择。要么让调用者传递日志记录发生位置的信息:
log(__LINE__,__FILE__,"Hello World");
或者使用宏来获得相同的输出。
log("Hello World");
//^--- log must be a macro if we want this __LINE__ in the log
这两种方法都非常不方便,因为要么用户在每次调用时都必须传递相同的参数,要么我们需要使用一个具有所有已知缺点的宏。使用source_location
,我们可以在不涉及任何宏的情况下获得log("Hello World");
,但仍然包括调用的行和文件,因为默认参数在调用位置被替换。例如:
#include <source_location>
#include <string>
#include <iostream>
void log(std::string message,const std::source_location& location = std::source_location::current())
{
std::cout << "Debug:"
<< location.file_name() << ':'
<< location.line() << ' '
<< message << '\n';
}
int main() {
log("hello");
log("world");
}
Debug:/app/example.cpp:15 hello
Debug:/app/example.cpp:16 world
发布于 2021-06-14 20:24:33
std::source_location的主要优势主要是方便,因为它用单一的、易于存储的结构表示源位置。
它还具有不基于预处理器魔法的优点,因此对于该语言来说,它不只是一个整型字面值,而是一个有效类型,从类型安全的角度来看,这要好得多。
如果您对旧的方法没意见,那么就没有理由更改好的、已经在运行的代码。不过,这通常适用于大多数新功能,而不仅仅是std::source_location。
https://stackoverflow.com/questions/67970038
复制相似问题