
在C++20中,std::source_location 是一个非常实用的特性,它允许你在运行时获取代码中的源文件位置信息,比如文件名、行号、函数名等。这个功能特别适合用于日志记录、断言检查和调试输出。
包含头文件与基本使用
要使用 std::source_location,需要包含头文件
这个类是隐式构造的,通常作为函数参数传入,默认参数可以直接捕获调用点的位置信息。
示例:
立即学习“C++免费学习笔记(深入)”;
#include#include void log(const std::string& message, const std::source_location& loc = std::source_location::current()) { std::cout << "文件: " << loc.file_name() << "\n" << "行号: " << loc.line() << "\n" << "函数: " << loc.function_name() << "\n" << "信息: " << message << "\n\n"; } void test_function() { log("这是一条调试信息"); }
输出类似:
文件: main.cpp 行号: 10 函数: test_function 信息: 这是一条调试信息
常用成员函数说明
std::source_location 提供了多个只读方法来获取位置信息:
- file_name():返回源文件的文件名(可能包含完整路径)
- line():返回当前行号(从1开始)
- column():返回列号(大多数编译器不支持,常返回0)
- function_name():返回所在函数的名称(经修饰的名称,可能较长)
注意:function_name() 返回的是编译器内部修饰后的名字,如果你希望看到清晰的函数名,可以配合工具如 c++filt 解析,或使用宏简化输出。
结合宏定义提升可读性
为了减少重复代码并提高灵活性,可以定义日志宏:
#define LOG(msg) log(msg, std::source_location::current())
// 使用方式
LOG("程序执行到这里");
这样每次调用 LOG 宏时,都会自动捕获当前位置信息,无需手动传参。
调试与错误追踪中的实际应用
在开发过程中,可以用 source_location 实现自定义断言机制:
void debug_assert(bool condition,
const std::string& msg = "",
const std::source_location& loc = std::source_location::current())
{
if (!condition) {
std::cerr << "断言失败!\n"
<< "文件: " << loc.file_name() << "\n"
<< "行号: " << loc.line() << "\n"
<< "函数: " << loc.function_name() << "\n"
<< "提示: " << msg << "\n";
std::abort();
}
}
// 使用示例
void divide(int a, int b) {
debug_assert(b != 0, "除数不能为零");
}
这种方式比传统 assert 更灵活,能输出更丰富的上下文信息。
基本上就这些。std::source_location 让日志和调试变得更智能,无需手动写文件名和行号,减少了出错可能,也提升了代码可维护性。只要编译器支持 C++20(如 GCC 11+、Clang 12+、MSVC 2019 16.10+),就可以放心使用。











