
在C++20中,std::source_location 提供了一种轻量且标准的方式,在运行时获取代码的源文件名、行号、函数名等调试信息。相比传统的宏如 __FILE__ 和 __LINE__,它更灵活,且能自动捕获调用位置。
如何使用 std::source_location 获取文件名和行号
std::source_location 是一个类,定义在头文件 current())在调用点自动捕获位置信息。
基本用法如下:
#include#include void log(const std::source_location& loc = std::source_location::current()) { std::cout << "文件: " << loc.file_name() << "\n"; std::cout << "行号: " << loc.line() << "\n"; std::cout << "函数: " << loc.function_name() << "\n"; } int main() { log(); // 自动输出当前调用位置 return 0; }
输出结果类似:
立即学习“C++免费学习笔记(深入)”;
文件: main.cpp行号: 12
函数: main
支持的源位置信息字段
std::source_location 提供了多个成员函数来访问不同维度的源码信息:
- file_name():返回源文件的路径或文件名(编译器决定是否包含完整路径)
- line():返回当前行号(从1开始)
- column():返回列号(部分编译器可能不支持,通常为0)
- function_name():返回所在函数的名称(通常是经过修饰的名称)
注意:function_name() 返回的是编译器内部表示的函数名,可能包含命名空间和参数类型(即“name mangling”),可读性较差。若需清晰名称,建议手动传入或结合其他调试工具。
在日志和断言中的实用场景
将 std::source_location 集成到日志系统或断言机制中,可以显著提升调试效率。
例如,实现一个带位置信息的调试宏:
#define DEBUG_LOG() \
log(std::source_location::current())
// 使用
DEBUG_LOG(); // 自动打印调用处的文件、行号
或者用于自定义断言:
void assertion_failed(const std::source_location& loc)
{
std::cerr << "断言失败!\n"
<< "位置: " << loc.file_name()
<< ":" << loc.line() << "\n";
}
#define MY_ASSERT(cond) \
do { if (!(cond)) assertion_failed(std::source_location::current()); } while(0)
注意事项与兼容性
std::source_location 是 C++20 特性,需确保编译器支持:
- GCC 11+(启用 -std=c++20)
- Clang 12+(-std=c++20)
- MSVC 19.29+(Visual Studio 2019 16.10)
如果项目暂未升级到 C++20,可考虑使用第三方库(如 Boost.Stacktrace)或封装传统宏 __FILE__、__LINE__ 模拟类似功能。
另外,由于 std::source_location::current() 是隐式生成的,不能跨线程传递后再期望反映原始位置——它只在被调用时捕获当前上下文。











