You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C++20的std::source_location不提供长度以避免性能损耗?

关于C++20 std::source_location的性能疑问

先看这段日志函数代码:

void Log(std::string_view       msg,
    std::source_location const& loc = std::source_location::current()) {
    
    // 存在性能损耗!
    auto const n = std::strlen(loc.file_name()); 
    auto s = ""s;
    s.resize(msg.size() + n);

    std::memcpy(&s[0], msg.data(), msg.size());
    std::memcpy(&s[msg.size()], loc.file_name(), n);

    // sendToRemoteMachine(s); 
}

显然,如果std::source_location::file_name返回std::string_view,就能直接获取字符串长度,避免调用strlen带来的性能损耗。毕竟std::source_location::file_name返回的是编译期生成的只读信息,编译器完全可以将其封装到std::string_view对象中。

那么为什么C++20的std::source_location不直接提供长度信息,或者返回std::string_view呢?


更新

有一篇相关文章《std::source_location 设计缺陷》专门讨论了这一设计的不合理之处。


问题解答

你指出的性能损耗确实存在——每次调用strlen(loc.file_name())都会遍历整个文件名字符串,而文件名作为编译期确定的常量,其长度本可以直接获取。关于标准如此设计的原因,主要有以下几点:

  • 兼容性优先:C++标准库设计时会优先考虑与现有代码的兼容。传统的__FILE__宏返回const char*类型,std::source_location::file_name()沿用这一返回类型,使得依赖__FILE__的旧代码可以平滑迁移到std::source_location,无需修改字符串处理逻辑。
  • 标准制定的权衡:虽然从技术实现上,编译器完全可以在编译期计算出文件名长度,并将其存储到std::source_location对象中(或直接返回std::string_view),但标准委员会可能认为,这一优化带来的收益不足以抵消兼容性成本,或者在提案阶段未充分讨论该方向的优化。
  • 实现灵活性:返回const char*给编译器留下了更多实现空间,比如直接复用现有__FILE__的字符串存储,无需额外维护长度信息,降低了编译器实现的复杂度。

规避性能损耗的方案

如果你想避免strlen的开销,可以自行封装一个工具函数,在编译期将文件名转换为std::string_view:

#include <source_location>
#include <string_view>

constexpr std::string_view get_file_name(std::source_location const& loc) {
    return std::string_view(loc.file_name());
}

std::string_view的构造会在编译期自动计算出字符串长度,后续使用时直接调用size()即可,无需再调用strlen。


内容的提问来源于stack exchange,提问作者xmllmx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 14:58:15