采用何种工具来查看型别推导结果,取决于你在软件开发过程的哪个阶段需要该信息。主要研究三个可能的阶段:撰写代码阶段、编译阶段、运行时阶段。

  IDE编译器

  IDE中的代码编译器通常会在你将鼠标指针选停止某个程序实体,如变量、形参、函数等时,显示出该实体的型别。例如以下这段代码:

const int theAnswer = ;
auto x = theAnswer;
auto y = &theAnswer;

  IDE编译器很可能会显示出,x的型别推导结果是int,而y则是const int*。

  而让这种方法奏效,代码就多多少少要处于一种可编译状态。因为让IDE提供此类信息的工作原理是让C++编译器(或至少也是其前端)在IDE内执行一轮。如果该编译器不能在分析你的代码时得到足够的有用信息,自然也就无法显示出推导除了何种型别。

  对于像int这样的平凡型别,从IDE能得到的信息大体良好。不过你很快就会看到,一旦较为复杂的型别现身,IDE显示的信息就不太有用了。

  编译器诊断信息

  想要让编译器显示其推导出的型别,一条有效的途径是使用该型别推导某些编译错误。而报告错误的消息几乎肯定会提及导致该错误的型别。

  

  运行时输出

  Boost的TypeIndex库(常写作Boost.TypeIndex),虽说该库不是C++的一部分,但IDE和像TD这样的模板也不是。Boost库(可从boost.com获得)的好处还不止于此,他跨平台、开源。这样一来,Boost库和那些依赖标准库的代码有几乎同样的可移植性。

  下面介绍一下函数f是如何在使用Boost.TypeIndex的条件下产生精确的型别信息的:

#include <boost/type_index.hpp>

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

  这种方法的工作原理是函数模板boost::typeindex::type_id_with_cvr接受一个型别实参(我们想要获取信息的型别),而且不会移除const、volatile和引用饰词(这也是改模板的名字中为什么含有with_cvr字样),该函数模板返回一个boost::typeindex::type_index对象,它利用成员函数pretty_name产生一个包含人类可读的型别表示的std::string。

std::vector<Widget> createVec();    //工厂函数

const auto vw = createVec();         //使用工厂函数返回值初始化vw

if(!vw.empty()) {
f(&vw[]); //调用f
...
}

  在使用GNU和Clang编译器的情况下,Boost.TypeIndex产生了以下的(精准)输出:

T =     Widget const*
param = Widget const* const&

  微软编译器取得的结果本质上完全相同:

T =     class Widget const*
param = class Widget const* const&

  请记住无论是IDE编译器、编译器错误消息,还是像Boost.TypeIndex这样的库都仅仅是你弄明白你的编译器推导所得型别的辅助工具。他们都十分有用,但是说到底,理解条款1~条款3的型别推导知识这一点无可替代。

要点速记:

1、利用IDE编译器,编译器错误消息、和Boost.TypeIndex库常常能够查看到推导而得的型别。

2、有些工具产生的结果可能会无用,或者不准确。所以,理解C++型别推导规则是必要的。

Effective Modern C++ 条款4:掌握查看型别推导结果的方法的更多相关文章

  1. Effective Modern C++ ——条款6 当auto型别不符合要求时,使用带显式型别的初始化物习惯用法

    类的代理对象 其实这部分内容主要是说明了在STL或者某些其他代码的容器中,在一些代理类的作用下使得最后的返回值并不是想要的结果. 而他的返回值则是类中的一个容器,看下面的一段代码: std::vect ...

  2. Effective Modern C++ 条款2:理解auto型别推导

    在条款1中,我们已经了解了有关模板型别的推导的一切必要知识,那么也就意味着基本上了解了auto型别推导的一切必要知识. 因为,除了一个奇妙的例外情况,auto型别推导就是模板型别推导.尽管和模板型别推 ...

  3. Effective Modern C++ ——条款2 条款3 理解auto型别推导与理解decltype

    条款2.理解auto型别推导 对于auto的型别推导而言,其中大部分情况和模板型别推导是一模一样的.只有一种特例情况. 我们先针对auto和模板型别推导一致的情况进行讨论: //某变量采用auto来声 ...

  4. Effective Modern C++ 条款3:理解decltype

    说起decltype,这是个古灵精怪的东西.对于给定的名字或表达式,decltype能告诉你该名字或表达式的型别.一般来说,它告诉你的结果和你预测的是一样的.不过,偶尔它也会给出某个结果,让你抓耳挠腮 ...

  5. Effective Modern C++ ——条款5 优先选择auto,而非显式型别声明

    条款5 对于auto ,他的好处不仅仅是少打一些字这么简单. 首先在声明的时候, 使用auto会让我们养成初始化的习惯: auto x;//编译不通过必须初始化. 再次对于auto而言,它可以让我们定 ...

  6. Effective Modern C++ ——条款7 在创建对象时注意区分()和{}

    杂项 在本条款的开头书中提到了两个细节性问题: 1.类中成员初始化的时候不能使用小括号. 如: class A { int a(0);//错误 }; 2.对于原子性类别的对象初始化的时候不能使用= 如 ...

  7. 《Effective Modern C++》翻译--条款4:了解怎样查看推导出的类型

    条款4:了解怎样查看推导出的类型 那些想要了解编译器怎样推导出的类型的人通常分为两个阵营. 第一种阵营是实用主义者.他们的动力通常来自于编敲代码过程中(比如他们还在调试解决中),他们利用编译器进行寻找 ...

  8. Effective Modern C++  条款1:理解模板型别推导

    成百上千的程序员都在向函数模板传递实参,并拿到了完全满意的结果,而这些程序员中却有很多对这些函数使用的型别是如何被推导出的过程连最模糊的描述都讲不出来. 但是当模板型别推导规则应用于auto语境时,它 ...

  9. Effective Modern C++翻译(5)-条款4:了解如何观察推导出的类型

    条款4:了解如何观察推导出的类型 那些想要知道编译器推导出的类型的人通常分为两种,第一种是实用主义者,他们的动力通常来自于软件产生的问题(例如他们还在调试解决中),他们利用编译器进行寻找,并相信这个能 ...

随机推荐

  1. C# 获取今天是星期几

    //获取今天是星期几 string[] Day = new string[] { "星期日", "星期一", "星期二", "星期 ...

  2. 《Practices of an Agile Developer:Woring in the Real World》读书笔记 PB16110698(~3.22)第三周

    <Practices of an Agile Developer:Woring in the Real World>读书笔记  本周我阅读了<高效程序员的45个习惯:敏捷开发修炼之道 ...

  3. array_map、array_walk、array_filter三个函数的区别

    array_walk --- 使自定的函数能处理数组的每个元素 bool array_walk ( array &array, callback funcname [, mixed userd ...

  4. Android开发 音视频开发需要了解的专业术语知识

    前言 在摸索一段时间的音视频开发后,越来越发现这个坑的深度真是特别的深. 除了了解Android自带的音视频处理API以外,还得了解一些视频与音频方面的知识.这篇博客就是主要讲解这方面的专业术语.内容 ...

  5. 【JZOJ3337】wyl8899的TLE

    description wyl8899今天也很刻苦的在做老师布置下来的题目! 这一天老师布置的题目是这样的: 给出两个仅含小写字母的字符串A和B,输出最大的k,使得A[1..k]是B的子串. A和B的 ...

  6. pytorch基础(1)

    基本数据类型和tensor import torch import numpy as np #array 和 tensor的转换 array = np.array([,]) tensorArray = ...

  7. 关于H5裁剪图片后,直传阿里云的一些问题

    这段时间在工作中碰到一个需要在h5裁剪图像,然后直传阿里云的需求.图中遇到了一些小问题,分享出来大家都看看. h5裁剪图像:cropper.js是一个神器啊关于用法,网上可以收罗出大量的帖子,这里我就 ...

  8. WCF服务编程-基础

    WCF是微软建立新一代的分布式应用及面向服务应用的标准平台,是基于原有.NET Framework 2.0的扩展.虽然在WCF发布不久就已经在项目中使用WCF技术了.但是由于在项目中还没有较大规模的应 ...

  9. Android基础控件DatePicker的使用

    1.简介 DatePicker日期选择器,自带spinner和calendar两种模式,相关属性: android:calendarTextColor : 日历列表的文本的颜色 android:cal ...

  10. 左神算法进阶班4_2累加和为aim的最长子数组

    [题目] 给定一个数组arr,和一个整数aim,求在arr中,累加和等于num的最长子数组的长度 例子: arr = { 7,3,2,1,1,7,7,7 } aim = 7 其中有很多的子数组累加和等 ...