不能。std::source_location::function_name()返回编译器生成的符号名(如mangled名"_z12my_functionv"),非可读c++函数名;gcc/clang需调用abi::__cxa_demangle()解析,msvc返回近似可读名但格式不稳定;推荐使用__function__宏替代。

std::source_location 能否直接获取函数名
不能。std::source_location::function_name() 返回的是编译器生成的符号名(如 "main" 或 "_Z12my_functionv"),不是可读的 C++ 函数名,且标准未规定其格式——GCC/Clang 返回 mangled 名(需 demangle),MSVC 返回近似可读名但不保证稳定。
如何在 GCC/Clang 下获得可读函数名
需要手动 demangle。依赖 <cxxabi.h></cxxabi.h>(GNU ABI)或 <experimental></experimental>(C++20)+ 运行时解析:
-
std::source_location::function_name()拿到的是 mangled 字符串,例如"_Z12my_functionv" - 调用
abi::__cxa_demangle()解析,注意它会 malloc 内存,必须free() - Demangle 失败时返回原字符串,不能假设一定成功
#include <source_location>
#include <abi>
#include <memory>
#include <iostream><p>std::string demangled_name(const std::source_location& loc) {
const char<em> mangled = loc.function_name();
int status = 0;
char</em> unmangled = abi::__cxa_demangle(mangled, nullptr, nullptr, &status);
if (status == 0 && unmangled) {
std::unique_ptr<char void>)(void)> guard{unmangled, [](void* p) { free(p); }};
return std::string{unmangled};
}
return std::string{mangled};
}</char></p>
<p>void my_function() {
auto loc = std::source_location::current();
std::cout </p></iostream></memory></abi></source_location>
MSVC 下更简单但有局限
MSVC 的 std::source_location::function_name() 通常返回类似 "void __cdecl my_function(void)" 的字符串,可正则提取或粗略截取,但不推荐用于生产——格式随编译器版本变化,且不处理模板实例化名。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 不要用
std::string_view(loc.function_name()).substr(5)这类硬切,__cdecl可能变成__stdcall - 若只用于调试日志,可做保守 fallback:匹配首个字母开头、直到空格或括号前的部分
- 无法可靠区分
foo<int></int>和foo<double></double>
替代方案:宏 + __FUNCTION__ 更实用
如果目标只是打印当前函数名(非严格标准合规),__FUNCTION__(GCC/Clang/MSVC 都支持)比 std::source_location 更直接、零开销、格式确定:
-
__FUNCTION__是预处理器宏,展开为纯字符串字面量,无运行时成本 - 对模板函数,GCC/Clang 返回
"foo<int>"</int>,MSVC 返回"foo<int>"</int>(带空格),基本可用 - 不依赖 C++20,兼容 C++11 起
#define LOG_FUNCTION() std::cout <p>真正麻烦的是跨平台统一格式和模板名解析——没有银弹,得按实际日志需求权衡:要标准就接受 mangled 名 + demangle;要简单就用宏;要精确控制就结合调试信息(DWARF/PDB)解析,但那已超出 <code>std::source_location</code> 范畴。</p>
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










