条款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 进行授权