簡體   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