为何__METHOD_NAME__宏需要进行内存拷贝?
提取带类名的函数名并放入只读段的实现
我的思路源自Stack Overflow的一个回答,我给string_view末尾添加了'\0',这样就能用data()适配printf、spdlog这类工具。我用宏来打印带类名的函数名,但发现编译器无法内联这个字符串,必须先将其拷贝到栈中。想请教如何让编译器把处理后的字符串放到只读段(就像const char*那样)?
最初的实现代码:
template<std::size_t N> consteval const std::array<char, N> __get_function_name(const char * arr) { std::array<char, N> data {}; std::string_view prettyFunction(arr); size_t bracket = prettyFunction.rfind("("); size_t space = prettyFunction.rfind(" ", bracket) + 1; size_t i; for (i = 0; i < bracket - space; i += 1) { data[i] = arr[space + i]; } data[i] = '\0'; return data; } #define __METHOD_NAME__ __get_function_name<strlen(__PRETTY_FUNCTION__)>(__PRETTY_FUNCTION__).data()
感谢@n.m.和user17732522的帮助,我最终得到了一个可行版本,但这个方案需要两次搜索'('和' ',可能会增加编译时间。
后来我做了更新,仅调用一次rfind(" "),优化后的代码:
#include <array> #include <string_view> constexpr size_t my_func_end(const char * arr) { std::string_view prettyFunction(arr); return prettyFunction.rfind("("); } constexpr size_t my_func_start(const char * arr, const size_t end) { std::string_view prettyFunction(arr); return prettyFunction.rfind(" ", end) + 1; } template<std::size_t S, std::size_t E> constexpr const std::array<char, E - S + 1> my_get_function_name(const char * arr) { std::array<char, E - S + 1> data {}; size_t i; for ( i = 0; i < E - S; i += 1) { data[i] = arr[S + i]; } data[i] = '\0'; return data; } template<auto tofix> struct fixme { static constexpr decltype(tofix) fixed = tofix; }; #define __METHOD_NAME_ARRAY__(x) my_get_function_name<my_func_start(x, my_func_end(x)), my_func_end(x)>(x) #define __METHOD_NAME__ (fixme<__METHOD_NAME_ARRAY__(__PRETTY_FUNCTION__)>::fixed.data())
我不确定编译器是否会缓存这些计算结果,如果可以的话,这个方案就足够用了。
内容的提问来源于stack exchange,提问作者Kang Jianbin
相关产品推荐
相关产品推荐

