第四节 · 拟态 · 自动推断类型
有时候,我们在日常与他人交流时,所说的话会省略一部分内容,而对方仍然能理解意思:
你看着办(如果这事情能行,你就尝试去做做看)。
不行就停下来(如果你做不下去,就先停下来吧)。
太贵了(这一套设备太贵了,买不起)。
我们可以发现,这些省略句都需要处于一定的语境下。没有上下文的帮助,对方很难理解句子的意思,或错误地以为是其它的含义。
在 C++ 中,我们同样可以如此——通过上下文中的一些信息,可以让编译器自动推断出某个变量应当是什么类型。下面,我们就来具体了解下它的原理。
有时,我们会写一些挺复杂的类型,就像这样:
const char[20] name = "langyo";
constexpr long long size = 10001L;
const double pi = 3.14159265;很显然,写这么长的类型真的很费事。
怎样偷懒呢?使用 auto 就可以了:
auto name = "langyo";
constexpr auto size = 10001L;
const auto pi = 3.14159265;auto 是一种特殊的数据类型,它可以根据定义变量时所给的初始化值,自动推断出此变量的类型。就刚刚的例子而言,"langyo" 推断得到的是const char *,10001L 推断得到的是 long long,3.14159265 推断得到的是 double。
auto 之上也可以额外添加类型标识,如 const、constexpr 、* 与 &。在刚刚的例子中,constexpr auto 与 const auto 便分别被推断为 constexpr long long 与 const double。
就基本数据类型而言,auto 在推断时遵循一些简单的规则:
字符串字面量转换为
const char[](也可以理解为const char*)。整型数字字面量默认转换为
int。浮点型数字字面量默认转换为
double。字符字面量默认转换为
char。
当然,auto 也可以直接凭一个现有的变量推断类型:
有时候,我们并不方便直接使用 auto 声明新变量。也许是因为我们不能使用 auto 默认的推断效果,也许我们只需要某个变量的类型:
此时,auto 便显得有些有心无力了。我们需要一个能具体指定为某变量类型的类型。
怎么办呢?我们可以使用 decltype:
decltype 可以接受字面量、变量、常量等对象,其格式如下:
decltype 与 auto 有些类似,都是自动推断类型,并且其附近同样可以添加像 const 之类的类型限定。不同之处在于,auto 直接通过检查初始化对象推断类型,而 decltype 则是检查由开发者手动指定的对象来推断类型。decltype 不对所提供的对象作出额外限制,但提取得到的类型可能会丢失一些被提取源头类型的一部分属性,具体机制会在以后的章节讨论。
另外,decltype 还有一种特殊格式:
如果仅仅用作字面量初始化,也就是像数字、字符串之类的,它与 auto 的表现其实没有多大区别。不过,当它用在函数的返回值或以函数返回值初始化的变量时,它的工作机制会有所变化。我们将在未来学习函数相关的内容时具体深入探究。
auto 与 decltype 两种自动推断类型在现代 C++ 程序中经常出现,它们是节约思考事件、提高编程效率的利器。有了它们,我们就无需为了类型一事大量翻阅文档与他人的源代码,并且也减小了类型书写错误的概率。
Last updated