持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第27天,点击查看活动详情
decltype可以获取变量或者表达式的类型,但是获取到的类型只能用于定义其他的变量和类型,不能打印出来,也不能用来操作。
IDE Editors
最简单的就是依靠C++的IDE帮你识别出decltype的返回类型,IDE毕竟不是万能的,所以你要识别的类型要尽可能的简单,不能过于复杂。
Compiler Diagnostic
借助于编译器的诊断错误信息。通过错误使用decltype推导出来的类型让编译器报出编译错误,在编译错误的信息中可以发现decltype推导出来的类型名称。例如下面的这个例子:
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template<typename T>
class TD;
int main()
{
const int theAnswer = 42;
auto x = theAnswer;
auto y = &theAnswer;
TD<decltype(x)> xtype;
TD<decltype(y)> xtype;
}
/* error: aggregate ‘TD xtype’ has incomplete type and cannot be defined error: aggregate ‘TD<const int*> xtype’ has incomplete type and cannot be defined */
Runtime Output
最后一种方式就比较专业了,而且还是运行时获取,不光光可以用来验证decltype的返回类型,还可以做运行时的检查,和一些额外的操作,实现的手段则是利用了typeinfo,
#include <typeinfo>
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template<typename T>
class TD;
int main()
{
const int theAnswer = 42;
auto x = theAnswer;
auto y = &theAnswer;
cout<<typeid(x).name()<<endl;
cout<<typeid(y).name()<<endl;
}
/*
i
PKi
*/
i int P point K const
const int*
BOOST
到此为止typeinfo看似解决了问题,其实不然,通过typeinfo得到的类型会忽略cv限制符还有引用,真的是差强人意啊。但是对const的指针类型是不会忽略const限制符的。
using boost::typeindex::type_id_with_cvr;
type_id_with_cvr<decltype(param)>().pretty_name()
int main() {
int x;
std::cout << demangle(typeid(decltype(x)).name()) << std::endl;
}
另一种方式
总结
- 类型推导可以借助于IDE,或者是编译器的错误输出以及Boost TypeIndex库
- 一些工具的类型推导结果可能是对我们所有帮助的,但是不一定是准确的,因此理解C++的类型推导规则仍然是必不可少的