Item4 Know how to view deduced types【Effective Modern C++中文版】

[复制链接]

该用户从未签到

759

主题

763

帖子

4660

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4660
跳转到指定楼层
楼主
发表于 2018-1-9 08:48:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

想要查看内容赶紧注册登陆吧!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
Item3中学习了C++11新特性decltypedecltype可以获取变量或者表达式的类型,但是获取到的类型只能用于定义其他的变量和类型,不能打印出来,也不能用来操作。毕竟是编译期实现,用来做类型反射就算了,那么至少也应该可以打印输出下吧,毕竟书中得来终觉醒。那么本文就介绍几种方法来得到decltype的返回类型的名字。
  • IDE Editors
    最简单的就是依靠C++的IDE帮你识别出decltype的返回类型,IDE毕竟不是万能的,所以你要识别的类型要尽可能的简单,不能过于复杂。
  • Compiler Diagnostic
    借助于编译器的诊断错误信息。通过错误使用decltype推导出来的类型让编译器报出编译错误,在编译错误的信息中可以发现decltype推导出来的类型名称。例如下面的这个例子:
    1. template<typename T>
    2. class TD

    3. TD<decltype(x)> xType;
    复制代码
    使用g++编译后,会出现编译出错,诊断信息如下:
  • 从上面的诊断信息就可以得出decltype(x)的结果就是int。
  • Runtime Output
    最后一种方式就比较专业了,而且还是运行时获取,不光光可以用来验证decltype的返回类型,还可以做运行时的检查,和一些额外的操作,实现的手段则是利用了typeinfo
    1. #include <typeinfo>
    2. int x = 0;
    3. std::cout << typeid(decltype(x)).name() << std::endl;
    复制代码
    上面会输出x的类型的名称,这里应该会输出int,但也不尽然,typeid的输出结果取决于编译器,MSVC的输出是int,而g++的输出则是i,也就是c++对int的名称重写后的结果。g++其实也可以实现和MSVC的输出结果一样,
    1. #include <string>
    2. #include <cxxabi.h> // 名称demangle
    3. #include <memory>
    4. #include <typeinfo>
    5. #include <iostream>

    6. std::string demangle(const char* name) {

    7.     int status = -4; // some arbitrary value to eliminate the compiler warning

    8.     // enable c++11 by passing the flag -std=c++11 to g++
    9.     std::unique_ptr<char, void(*)(void*)> res {
    10.         abi::__cxa_demangle(name, NULL, NULL, &status),
    11.         std::free
    12.     };

    13.     return (status==0) ? res.get() : name ;
    14. }

    15. int main() {
    16.   int x;
    17.   std::cout << demangle(typeid(decltype(x)).name()) << std::endl;
    18. }
    复制代码
    到此为止typeinfo看似解决了问题,其实不然,通过typeinfo得到的类型会忽略cv限制符还有引用,真的是差强人意啊。但是对const的指针类型是不会忽略const限制符的。具体可以参考typeid获取完整类型幸好可以借助于boost的Boost.Type-Index库得到精确的类型。
    1. template<typename T>
    2. void f(const T& param) {
    3.   using std::cout;
    4.   using boost::typeindex::type_id_with_cvr;

    5.   cout << "param = "
    6.        << type_id_with_cvr<T>().pretty_name()
    7.        << '\n';

    8.   cout << "param = "
    9.        << type_id_with_cvr<decltype(param)>().pretty_name()
    10.        << '\n';
    11. }
    复制代码


分享到:  QQ好友和群QQ好友和群
收藏收藏
回复

使用道具 举报

快速回复高级模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表