[英]Compiler independent class name
我需要打印 class 的名称,例如
template<typename... Args>
struct S{};
使用typeid(S<int,std::vector<double>>).name()
打印有代表性的东西相当简单。 使用boost demangle ,它甚至可以在 gcc 上读取。
有什么方法可以获取名称,以便不同编译器之间的名称相同?
并不真地。 损坏的名称通常是特定于编译器的。 请参阅Wikipedia上标题为“不同编译器如何处理相同功能”的表格
#include <string_view>
#include <vector>
template<typename... Args>
struct S{};
template <typename T>
constexpr auto type_name()
{
std::string_view name, prefix, suffix;
#ifdef __clang__
name = __PRETTY_FUNCTION__;
prefix = "auto type_name() [T = ";
suffix = "]";
#elif defined(__GNUC__)
name = __PRETTY_FUNCTION__;
prefix = "constexpr auto type_name() [with T = ";
suffix = "]";
#elif defined(_MSC_VER)
name = __FUNCSIG__;
prefix = "auto __cdecl type_name<";
suffix = ">(void)";
#endif
name.remove_prefix(prefix.size());
name.remove_suffix(suffix.size());
return name;
}
int main()
{
#ifdef _MSC_VER
static_assert(type_name<S<int, std::vector<double>>>() == "struct S<int,class std::vector<double,class std::allocator<double> > >");
#else
static_assert(type_name<S<int, std::vector<double>>>() == "S<int, std::vector<double, std::allocator<double> > >");
#endif
}
不,没有可移植的方法来获取跨所有平台的任意类型的名称作为字符串。
您可能会编写一个 function 模板,该模板使用特定于平台的代码来确定模板参数的名称,但这很难做到,而且很脆弱。
或者,如果您只想要类型的名称,或者您愿意为需要名称的每种类型注册名称,那么您可以执行以下操作:
some_library::register_type_name<some_type>("some_type");
some_library::register_type_name<some_other_type>("some_other_type");
将条目添加到typeid
的内部 map 到字符串。 这可以隐藏在像REGISTER_TYPE(x)
这样的宏后面,但仍然需要为每种类型完成。
然后,您可以轻松编写some_library::lookup_type_name<some_type>()
来搜索已注册的类型并返回字符串。 你也可以为S
编写一个重载,它也会查找它的模板参数的名称。
您可以编写一个库,为所有标准类型提供名称,加上标准类型的容器,并使其可扩展为项目特定类型......
这正是 Celma 中的“类型名称”子库所做的。
查看测试文件中的使用示例: https://github.com/Gemini67/Celma/blob/master/src/library/common/test/test_type_name.cpp
整个库的起点在这里: https://github.com/Gemini67/Celma
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.