讲师中心 微信公众号
AI工具推荐 视频效率加速

c++ c++20 source_location c++如何获取当前源码的文件名和行号

轻萱酱_5425

轻萱酱_5425

发布时间:2026-03-19 20:54:00

|

189人浏览过

|

来源于php中文网

原创

std::source_location 是 C++20 标准的类型安全源位置获取方案,需用 ::current() 显式调用获取调用点信息,不可默认构造或在包装函数内转发;相比 __FILE__/__LINE__ 宏,它支持传参、模板、constexpr,且路径行为稳定、无预处理缺陷。

c++ c++20 source_location c++如何获取当前源码的文件名和行号

用 std::source_location 直接取文件名和行号

在 C++20 中,std::source_location 是标准方案,不用宏、不依赖编译器扩展,类型安全且可传递。它本质是个轻量结构体,构造时自动捕获调用点的源码位置。

常见错误是手动传参或试图默认构造:std::source_location::current() 必须显式调用,且必须在目标函数内调用(不能在包装函数里偷懒转发)。

  • 必须写成 std::source_location loc = std::source_location::current();,不能写 std::source_location loc;(后者是默认构造,字段全为 0 或空字符串)
  • 如果封装成日志函数,要确保 std::source_location::current() 出现在最外层调用处,比如 log("msg", std::source_location::current()),而不是在 log 函数体内调用
  • loc.file_name() 返回 const char*,内容生命周期绑定到编译单元,可直接用,但别存指针长期引用(虽然通常没问题,但标准不保证)

为什么不用 __FILE__ 和 __LINE__ 宏

宏能用,但和 std::source_location 不是同一层次的东西:宏是预处理期文本替换,无类型、不可传递、无法参与模板推导;而 source_location 是运行时值,支持拷贝、传参、存储、甚至序列化(只要字段可访问)。

典型翻车场景是想把位置信息塞进类成员或 std::format:

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

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

  • 写 std::format("at {}:{}\n", __FILE__, __LINE__) 看似可行,但 __FILE__ 可能带绝对路径,长度爆炸,且无法控制编码(Windows 上常是窄字符 GBK)
  • 宏无法作为模板参数,也不能用于 constexpr 上下文做编译期分支(而 source_location::current() 在函数内是 constexpr 友好的)
  • 某些构建系统或 IDE 会重写 __FILE__(比如用相对路径替换),导致日志里路径不一致;source_location::file_name() 行为由标准规定,更稳定

source_location 的兼容性与性能开销

它不是零成本抽象,但开销极小:只读取当前栈帧的调试信息(实际是编译器在调用点埋的常量数据),没有函数调用、无内存分配、不触发任何运行时逻辑。

  • Clang 12+、GCC 11+、MSVC 19.29+ 支持;低于这些版本会编译失败,别指望降级 fallback —— 没有标准替代品
  • 启用 -g 或 /Zi 并不影响 source_location 工作,它不依赖调试符号,而是编译时硬编码字面量
  • 注意:如果函数被内联(尤其是 inline 或 [[always_inline]]),source_location::current() 捕获的是调用点位置,不是函数定义处 —— 这正是你想要的行为

一个安全的日志封装示例

直接贴可用代码,重点看调用方式和参数位置:

#include <source_location>
#include <iostream>
#include <string_view>
<p>void log(std::string_view msg,
const std::source_location loc = std::source_location::current()) {
std::cerr << loc.file_name() << ":" << loc.line()
<< " - " << msg << "\n";
}</p><p>// 正确用法:位置信息自动来自 caller
int main() {
log("starting up"); // 输出类似:main.cpp:12 - starting up
return 0;
}</p>

容易忽略的一点:std::source_location 默认参数只能用于非模板函数或明确指定模板参数的函数;如果写成函数模板,需额外约束或显式传参,否则可能因 SFINAE 失败或推导歧义报错。

相关文章

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

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

下载

相关标签:

c++

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

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

相关专题

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

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

6024

2023.10.24

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

1709

2023.07.31

python中的format是什么意思
python中的format是什么意思

python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1211

2024.06.27

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2138

2023.09.20

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

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

1698

2023.08.03

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

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

2604

2023.09.04

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

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

6024

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

5529

2023.11.24

OpenJDK JVM参数怎么调优
OpenJDK JVM参数怎么调优

Java应用运行缓慢,如何调整JVM参数?本专题介绍OpenJDK JVM性能调优的基本流程,涵盖性能指标确认、运行数据采集、内存配置和垃圾回收分析,帮助你先定位瓶颈,再通过对照测试验证效果,避免直接套用参数而影响应用稳定性。

0

2026.10.16

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn