提问人:Dmitry Logov 提问时间:10/23/2023 最后编辑:Jarod42Dmitry Logov 更新时间:10/23/2023 访问量:108
C++ 将 std::source_location::function_name() 作为字符串文字模板参数传递
c++ pass std::source_location::function_name() as string literal template argument
问:
我有这段代码,它返回宏在编译时提供的修改后的函数名称字符串:__PRETTY_FUNCTION__
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()
替换宏 如何将其作为模板参数传递?
有没有另一种方法可以将其作为 PrettifyFunctionName 中的值获取?__PRETTY_FUNCTION__
constexpr
答:
添加一个构造函数,该构造函数从 复制到数组中,就像当前循环一样,然后:SL
const char*
constexpr auto funcName = std::source_location::current().function_name();
constexpr auto resultName = PrettifyFunctionName<SL<mystrlen(funcName)+1>(funcName)>();
您将需要与自己等效地定义,因为没有标记 .mystrlen
strlen
std::strlen
constexpr
无法避免两次命名,因为它的类型不包含有关其长度的信息,并且未指定结果是否引用字符串文本。如果它引用字符串文本,则不能直接作为模板参数传递。funcName
function_name
但是,您可以用一些足够大的数字替换。如果实际函数名称太长,它将无法编译。mystrlen(funcName)+1
将字符串作为函数参数而不是模板参数传递可能更容易,假设您不需要字符串成为 later 类型的一部分。resultName
顺便说一句,我认为编译时的使用没有很好地指定。source_location
标记成员函数,指示它们应该在编译时可用,但结果仅指定为引用某些以 null 结尾的字节字符串。constexpr
function_name
它没有说明该字符串是否应该具有静态存储持续时间,以便指针可以存储在变量中,它是否可以引用字符串文字,以便它不能直接用作模板参数,以及它的元素是否可以在常量表达式中使用,以便可以在常量表达式中检查字符串的实际内容。(虽然第一种是从被标记中得出的。constexpr
current
consteval
但一个普遍的问题是,标记的库函数缺乏精确的规范,哪些是保证编译时使用的,哪些是不能的。constexpr
评论
source_location
上一个:为什么参数不是常量表达式?
下一个:C++ 编译中的别名声明错误
评论
const char*
不是有效的模板参数类型。但是,您应该能够制作一个函数constexpr auto PrettifyFunctionName(const char* function_name)
consteval auto PrettifyFunctionName(std::source_location)
constexpr auto resultName = PrettifyFunctionName(std::source_location::current());
= std::source_location::current()
std::source_location
current()