文章

条款4:类型推导结果的查看方式

使用 IDE、decltype、辅助模板等手段查看类型推导结果,避免因推导不透明而引发理解或调试困难。

条款4:类型推导结果的查看方式

条款4:类型推导结果的查看方式

选择什么工具查看类型推导,取决于希望在哪个阶段获取类型信息:编辑时编译时、或运行时

编辑时:通过 IDE 提示

  • 鼠标悬停即可查看变量/参数/函数的推导类型。
  • 需要代码处于基本可编译状态
1
2
3
const int theAnswer = 42;
auto x = theAnswer;       // IDE 显示为 int
auto y = &theAnswer;      // IDE 显示为 const int*
  • 对于复杂类型,IDE 展示的信息可能难以阅读甚至不准确。
  • 不同 IDE 和插件展示效果差异大。

编译时:利用编译器错误信息

利用未定义模板类触发错误,观察编译器推导出来的类型:

1
2
3
4
5
template<typename T>
class TD;  // Type Displayer

TD<decltype(x)> xType;
TD<decltype(y)> yType;

示例输出(GCC):

1
2
error: aggregate TD<int> xType has incomplete type
error: aggregate TD<const int *> yType has incomplete type
  • 错误信息中,模板实参即是类型推导结果。

运行时:使用 typeid().name()

1
2
std::cout << typeid(x).name() << '\n';
std::cout << typeid(y).name() << '\n';

解释器输出(不同平台):

  • GCC/Clang:输出如 "i" 表示 int"PKi" 表示 const int*
  • MSVC:更直观,输出 "int""const int*"

限制

  • 忽略引用、顶层 const,如 const T& 显示为 T
  • 对模板参数显示不准确

Boost.TypeIndex:精确显示类型

1
2
3
4
5
6
7
8
#include <boost/type_index.hpp>

template<typename T>
void f(const T& param) {
    using boost::typeindex::type_id_with_cvr;
    std::cout << "T =     " << type_id_with_cvr<T>().pretty_name() << '\n';
    std::cout << "param = " << type_id_with_cvr<decltype(param)>().pretty_name() << '\n';
}

示例输出:

1
2
T =     Widget const *
param = Widget const * const &
  • 保留 const、volatile、reference 修饰符,结果更接近真实类型。

总结

  • 工具只是辅助理解
  • 掌握 C++ 类型推导规则才是根本之道!
工具优点缺点
IDE快速方便,集成度高对复杂类型不够友好
编译器错误简洁明了,无依赖需要触发错误,效率较低
typeid().name()简单可运行信息不完整,忽略修饰符
Boost.TypeIndex准确完整,适合调试需要引入额外库,略繁琐
本文由作者按照 CC BY 4.0 进行授权