您的位置:首页 >C++20 source_location打印行号技巧
发布于2026-04-14 阅读(0)
扫一扫,手机访问
最常用写法是定义宏LOG_LINE()调用std::source_location::current(),日志函数按值接收默认参数;不可取地址或绑定引用,因返回纯右值;跨平台需校验line()==1且file_name()为空时回退。

std::source_location 本身不支持直接打印,必须显式调用 line()、file_name() 等成员函数才能拿到行号等信息;它只是个轻量值类型,不是格式化工具。
最常用写法是定义一个宏,把 std::source_location::current() 的调用“固定”在调用点展开:
#define LOG_LINE() std::source_location::current()
然后在日志函数中接收该参数(默认值避免每个调用都手动传):
void log(const char* msg, std::source_location loc = std::source_location::current()) {
printf("[%s:%d] %s\n", loc.file_name(), loc.line(), msg);
}调用时直接 log("user logged in") 就能打出真实调用处的行号——因为宏没参与,std::source_location::current() 是在调用点编译期求值的。
常见错误是试图取地址或绑定引用:
auto& loc = std::source_location::current(); —— 错,返回的是纯右值,引用绑定失败(GCC/Clang 报错 cannot bind non-const lvalue reference to an rvalue)const auto& loc = ... —— 虽然语法通过,但会延长临时对象生命周期,行为不可靠;不同编译器优化下可能捕获到宏展开位置而非真实调用点std::source_location,它只有 4 个 size_t 成员,开销极小C++20 标准接口统一,但底层实现依赖编译器扩展:
__builtin_SOURCE_LOCATION,需开启 -std=c++20 且不加 -fno-builtinline() == 1, file_name() == "")if (loc.line() == 1 && std::string_view(loc.file_name()).empty()) { /* fallback */ }注意:std::source_location::current() 的值完全由编译器在翻译单元内填充,无法被宏、内联函数或模板推导干扰——但如果你把它藏在中间函数里(比如封装一层再转发),那拿到的就是那一层的行号,不是原始调用点。想保真,就得让 current() 出现在最终日志调用的同一行。这是最容易忽略、也最难调试的点。
下一篇:《画质mxpro》广角开启教程
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9