如何将std::source_location::function_name()作为模板实参传递?
关于std::source_location::function_name()作为模板实参及constexpr获取的问题
原代码通过__PRETTY_FUNCTION__宏作为模板实参传递给编译期函数PrettifyFunctionName,实现函数名的修改:
template<size_t N> struct SL { char value[N]; constexpr SL(const char (&str)[N]) { for(size_t i = 0; i != N; ++i) value[i] = str[i]; } }; template<SL literal> consteval auto PrettifyFunctionName() { ... }
原调用方式:
constexpr auto resultName = PrettifyFunctionName<__PRETTY_FUNCTION__>();
现希望替换为std::source_location::function_name(),以下是具体解决方案:
一、将std::source_location::function_name()作为模板实参传递
std::source_location::function_name()返回const char*,无法直接作为SL类型的模板非类型参数传递,需要先将其转换为SL类型的编译期常量:
方案1:显式捕获并转换
在调用处先通过constexpr变量捕获函数名,再生成SL实例:
#include <source_location> // 编译期捕获当前函数名 constexpr auto current_func = std::source_location::current().function_name(); // 转换为SL类型的编译期常量 constexpr SL func_sl{current_func}; // 传递模板实参 constexpr auto resultName = PrettifyFunctionName<func_sl>();
方案2:封装辅助模板简化调用
利用模板默认实参的constexpr特性,直接在辅助模板中完成source_location的获取和转换:
#include <source_location> template<auto Loc = std::source_location::current()> consteval auto PrettifyFunctionNameHelper() { constexpr SL func_sl{Loc.function_name()}; return PrettifyFunctionName<func_sl>(); } // 调用时无需额外参数 constexpr auto resultName = PrettifyFunctionNameHelper();
二、其他在PrettifyFunctionName中获取constexpr函数名的方式
无需传递模板实参,直接在函数内部编译期获取函数名:
方式1:通过函数默认参数传递source_location
修改PrettifyFunctionName为普通consteval函数,利用默认参数获取当前位置的source_location:
#include <source_location> consteval auto PrettifyFunctionName( const std::source_location& loc = std::source_location::current() ) { constexpr auto func_name = loc.function_name(); // 此处编写函数名修改逻辑 ... } // 调用方式 constexpr auto resultName = PrettifyFunctionName();
方式2:用模板默认实参直接传递source_location
将std::source_location作为模板参数的默认值,直接在模板函数内部获取函数名:
#include <source_location> template<std::source_location Loc = std::source_location::current()> consteval auto PrettifyFunctionName() { constexpr auto func_name = Loc.function_name(); // 此处编写函数名修改逻辑 ... } // 调用方式 constexpr auto resultName = PrettifyFunctionName();
这种方式省去了SL类型的转换步骤,若后续处理不需要SL结构,会更简洁高效。
内容的提问来源于stack exchange,提问作者Dmitry Logov
相关产品推荐
相关产品推荐

