std::source_location多次调用是否保证复用同一对象?
std::source_location::current()调用的对象一致性问题
核心结论
无法保证同一位置多次调用std::source_location::current()会返回指向同一对象的引用,示例代码中三次func()调用打印的地址不一定相同。
标准层面的规则
C++20标准对std::source_location::current()的要求仅聚焦于返回对象的内容正确性:它必须包含调用位置的文件名、行号、函数名等准确信息,但并未强制要求所有同一位置的调用都返回同一个对象实例。
编译器实现的差异
不同编译器的实现逻辑可能导致不同结果:
- 部分编译器会为同一调用位置生成一个静态的
std::source_location实例,所有该位置的调用都返回指向这个静态实例的引用,此时打印的地址会完全相同。 - 另一些编译器可能在每次调用时构造临时对象(由于函数参数是
const引用,临时对象的生命周期会延长至函数调用结束),每次生成的临时对象存储地址不同,因此打印的地址也会不一样。
示例代码的具体分析
针对你提供的代码:
#include <source_location> #include <iostream> #include <format> void log(const std::source_location& location = std::source_location::current()) { std::cout << std::format("{}", static_cast<const void*>(&location)) << std::endl; } void func() { log(); } int main() { func(); func(); func(); }
默认参数std::source_location::current()会在每次调用log()时(也就是func()内的log()语句位置)被求值。如果编译器采用静态实例的实现,三次打印地址相同;如果采用临时对象的实现,地址则不同。
实践建议
- 若仅需获取源位置信息(如日志记录),直接使用对象提供的接口(
file_name()、line()等)即可,无需关心对象地址是否一致。 - 如需判断两个
std::source_location是否指向同一代码位置,应使用标准提供的==运算符比较对象内容,而非通过地址比较。
内容的提问来源于stack exchange,提问作者Walter Svenddal
相关产品推荐
相关产品推荐

