如何调试和打印模板别名类型 c++

问题描述

我有一些嵌套的 typedef 正在尝试调试。我想做的第一件事是将它们打印出来,以便我可以看到它们是如何实例化的。

例如

 using tt = std::conditional<conditionForType1,type_1,type_2>;

其中 type_1type_2 是另外两个评估的别名。如何打印 tttype_1type_2

内容

解决方法

一种快速而肮脏的方式:

template <typename T>
void print_type()
{
    #ifndef _MSC_VER
    std::cout << __PRETTY_FUNCTION__ << '\n';
    #else
    std::cout << __FUNCSIG__ << '\n';
    #endif
}

究竟打印什么取决于编译器。对于 print_type<int>();,我的 Clang 打印 void print_type() [T = int]

请参阅 this thread 以从此类字符串中删除除类型名称以外的任何内容。

,

我使用编译器来为我处理这个问题。通过声明一个类模板,如

template <typename T>
struct type;

并且不定义它,您可以在代码中使用它

int main()
{
    struct foo {};
    struct bar {};
    
    foo f;
    
    type<int>{};
    type<decltype(f)>{};
    type<bar>{};
}

这会给你一个编译器错误

main.cpp: In function 'int main()':
main.cpp:25:15: error: invalid use of incomplete type 'struct type<int>'
   25 |     type<int>{};
      |               ^
main.cpp:14:8: note: declaration of 'struct type<int>'
   14 | struct type;
      |        ^~~~
main.cpp:26:23: error: invalid use of incomplete type 'struct type<main()::foo>'
   26 |     type<decltype(f)>{};
      |                       ^
main.cpp:14:8: note: declaration of 'struct type<main()::foo>'
   14 | struct type;
      |        ^~~~
main.cpp:27:15: error: invalid use of incomplete type 'struct type<main()::bar>'
   27 |     type<bar>{};
      |               ^
main.cpp:14:8: note: declaration of 'struct type<main()::bar>'
   14 | struct type;
      |        ^~~~

它为您提供了模板参数中使用的类型作为方便的错误消息。

,

typeid 运算符返回 type_info 类型的对象,该对象具有 name() 方法。您可以使用它来获取该类型的字符串表示。

std::cout << typeid(tt).name() << '\n';

如果您使用 ,则可以调用 API 将名称分解为更易读的内容。在我的系统上,程序:

using tt = std::conditional<true,int,double>;

int main () {
    int status;
    auto &&ti = typeid(tt);
    char *pretty = abi::__cxa_demangle(ti.name(),&status);
    std::cout << ti.name() << '\n';
    std::cout << pretty << '\n';
    free(pretty);
}

产生输出:

St11conditionalILb1EidE
std::conditional<true,double>

Try it online!