0

0

c++如何使用std::source_location获取行号_c++ 20日志调试信息自动记录【指南】

尼克

尼克

发布时间:2026-01-02 10:53:02

|

739人浏览过

|

来源于php中文网

原创

c++kquote>std::source_location 是 C++20 引入的轻量结构体,用于编译期捕获调用点源码位置;它不依赖运行时堆栈,开销极低,需通过 std::source_location::current() 作为默认参数在日志函数中显式捕获。

c++如何使用std::source_location获取行号_c++ 20日志调试信息自动记录【指南】

std::source_location 是什么,为什么能自动记录行号

std::source_location 是 C++20 引入的轻量结构体,用于在编译期捕获调用点的源码位置信息。它不依赖运行时堆遍历,也不触发函数内联抑制(只要编译器支持 C++20 且未禁用),因此开销极低。关键在于:它不是“获取当前行号”,而是“让调用者把它的位置传进来”——这决定了你必须在日志宏里用 __LINE__ 或更规范的 std::source_location::current() 显式捕获。

如何正确声明日志函数并接收 source_location

直接把 std::source_location 当作函数参数传入即可,但注意默认值必须是编译期可求值的表达式。最常用写法是用静态成员函数 std::source_location::current() 作为默认实参:

void log_debug(const char* msg, const std::source_location loc = std::source_location::current()) {
    std::cout << "[" << loc.file_name() << ":" << loc.line() << "] " << msg << "\n";
}

调用时无需手动传参:log_debug("value is 42"); 就会自动记录调用点的文件名与行号。若手动传入(比如封装中间层),需确保调用点仍是最终用户代码位置,否则行号会偏移。

  • 不要在包装函数里直接写 std::source_location::current() —— 那会记录包装函数自身的行号
  • 若需支持多参数日志(如格式化字符串),建议用宏包裹,再转发给实际函数
  • loc.function_name() 在 GCC/Clang 中通常返回空字符串;MSVC 支持较好,但不可依赖

用宏封装避免手动传参和行号错位

纯函数调用无法解决“用户调用点 vs 包装函数”的行号偏移问题,必须用宏。宏展开发生在预处理阶段,std::source_location::current() 在宏体内求值,就落在用户代码行上:

立即学习C++免费学习笔记(深入)”;

10Web
10Web

AI驱动的WordPress网站自动构建器,托管和页面速度助推器

下载
#define LOG_DEBUG(msg) \
    log_debug(msg, std::source_location::current())

这样 LOG_DEBUG("x = " + std::to_string(x)); 记录的就是这行本身的行号。更进一步,可支持格式化:

#define LOG_INFO(fmt, ...) \
    do { \
        std::ostringstream _oss; \
        _oss << fmt; \
        log_info(_oss.str().c_str(), std::source_location::current()); \
    } while(0)

注意:__VA_ARGS__ 展开后不能直接传给 std::source_location::current(),因为逗号会破坏宏参数解析;必须先拼接好字符串再传。

  • 宏名全大写是惯例,避免与变量/函数名冲突
  • 使用 do { ... } while(0) 包裹可防止 if-else 分支中出现语法错误
  • GCC/Clang 默认启用 -std=c++20 后才支持 std::source_location;MSVC 需 VS 2019 16.8+

常见错误:行号总是固定在某一行或报编译错误

典型现象包括:所有日志都显示同一行号(比如总显示在 log.h 第 42 行),或编译报错 error: 'std::source_location::current' is not a constant expression

  • 忘记加 -std=c++20 或项目设置未启用 C++20 —— 这是最常见的原因
  • 在模板函数或 constexpr 上下文中误用 std::source_location::current() —— 它不是 constexpr 函数,不能用于常量表达式
  • std::source_location::current() 写在函数体内部而非默认参数位置,又没用宏 —— 行号永远是该函数定义处的行
  • 使用了旧版标准库(如 libstdc++ __cpp_lib_source_location 宏是否已定义

验证是否生效,可在不同文件、不同行各调用一次 LOG_DEBUG("test"),观察输出的 loc.line() 是否随调用位置变化。不变化,说明捕获点没落在用户代码上。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1435

2023.10.24

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

713

2023.08.22

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

81

2023.09.25

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

184

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

265

2023.10.25

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

249

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

205

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1435

2023.10.24

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

74

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 0.9万人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号