繁体   English   中英

编译器独立 class 名称

[英]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
}

是否可以在标准 C++ 中打印变量的类型?

不,没有可移植的方法来获取跨所有平台的任意类型的名称作为字符串。

您可能会编写一个 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM