【问题标题】:Compiler independent class name编译器独立类名
【发布时间】:2020-03-11 16:29:36
【问题描述】:

我需要打印一个类的名字比如

template<typename... Args>
struct S{};

使用typeid(S&lt;int,std::vector&lt;double&gt;&gt;).name() 打印具有代表性的东西相当简单。使用boost demangle,它甚至可以在 gcc 上读取。

有什么方法可以得到名字,所以不同编译器之间的名字是一样的?

【问题讨论】:

  • 只有编译器特定的魔法,因为 C++ 还没有反射。
  • 如果存在这样的功能,它可能对序列化/反序列化(以文本形式)有用。

标签: c++ visual-studio gcc boost c++17


【解决方案1】:

不是真的。损坏的名称通常是特定于编译器的。请参阅Wikipedia上标题为“不同编译器如何处理相同函数”的表格

【讨论】:

    【解决方案2】:

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

    您可能会编写一个函数模板,该模板使用特定于平台的代码来确定模板参数的名称,但这很棘手,而且很脆弱。

    或者,如果您只想要类型的名称,或者您愿意为需要名称的每种类型注册名称,那么您可以执行以下操作:

    some_library::register_type_name<some_type>("some_type");
    some_library::register_type_name<some_other_type>("some_other_type");
    

    将条目添加到typeid 的内部映射到字符串。这可以隐藏在像 REGISTER_TYPE(x) 这样的宏后面,但仍然需要对每种类型都进行。

    然后您可以轻松编写some_library::lookup_type_name&lt;some_type&gt;(),它会搜索已注册的类型并返回字符串。你也可以为S 编写一个重载,它也会查找它的模板参数的名称。

    【讨论】:

    • 有没有办法注册模板类型的每个实例化?
    • template&lt;typename ... Args&gt; std::string lookup_type_name&lt;MyTemplate&lt;Args...&gt;&gt;(){ stuff();}
    【解决方案3】:

    您可以编写一个库,为所有标准类型提供名称,加上标准类型的容器,并使其可针对项目特定类型进行扩展...

    这正是 Celma 中的“类型名称”子库所做的。

    查看测试文件中的用法示例: https://github.com/Gemini67/Celma/blob/master/src/library/common/test/test_type_name.cpp

    整个库的起点在这里: https://github.com/Gemini67/Celma

    【讨论】:

    • 我认为在提供的示例中可能出现的所有参数组合都不可能这样做
    • @Bomaz 是的。该库也可以处理 std::tuple ,它正是使用这种接口。
    • 它是否像示例中那样处理用户定义的、模板化的类型?那将非常有用
    • @Bomaz 不是自动的,但可以为用户定义的类型定义必要的部分模板特化,无论是否模板化。
    猜你喜欢
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-08
    相关资源
    最近更新 更多