一 静态类型、动态类型与类型推导
在编程语言的分类中,C/C++常被冠以“静态类型”的称号,而有的编程语言则称为“动态类型的”,比如Python。静态类型和动态类型的主要区别在于对变量进行类型检查的时间点。对于所谓的静态类型,类型检查主要发生在编译阶段;而对于动态类型,类型检查主要发生在运行阶段。形如Python等语言的变量“拿来就用”的特性,则需要归功于一个技术,即类型推导。
事实上,类型推导也可以用于静态类型的语言中。在C++11中,实现类型推导的方式之一就是auto,另外一个方式是decltype,这里主要讲auto。如下例:
#include <iostream>
using namespace std;
int main
{
auto name = "world.\n";
cout << "hello" << name << endl;
}
这里我们使用了auto关键字来要求编译器对变量name的类型进行自动推导。这里编译器根据它的初始化表达式的类型,推导出name的类型为char*。这里的atuo是作为类型指示符(int、float等都是类型指示符)来指示编译器,auto声明变量的类型必须由编译器来编译时期推导而得。
auto声明的变量必须被初始化,以使编译器能够从其初始化表达式中推导出类型。从这个意义上讲,auto并非一种“类型”声明,而是一个类型声明时的“占位符”,编译器在编译时期会将auto替代为变量实际的类型。
二 auto的优势
1 最大优势就是在拥有初始化表达式的复杂类型变量声明时简化代码。
比如:
#include <vector>
#include <string>;
void loopover(std::vector<std::string> &vs)
{
std::vector <std::string>::iterator i = vs.begin(); //想要使用iterator,往往需要书写大量代码
for (; i != vs.end(); ++i)
{
//...
}
}
auto改写:
#include <vector>
#include <string>;
void loopover(std::vector<std::string> &vs)
{
for (auto = vs.begin(); i != vs.end(); ++i)
{
//...
}
}
2 可以免除程序员在一些类型声明时的麻烦,或者避免一些在类型声明时的错误。比如整型与字符型进行加法运算后,表达式返回的是整型,这是一条隐式规则。
3 其“自适应”性能够在一定程度上支持泛型的编程。
比如:
template<typename T1, typename T2>
double Sum(T1&t1, T2&t2)
{
auto s = ti + t2; //s的类型会在模板实例化是被推导出来
return s;
}
int main()
{
int a = 3;
long b = 5;
float c = 1.0f, d = 2.3f;
Sum<int, long>(a, b); //s的类型被推导为long
Sum<float, float>(c, d); //s的类型被推导成float
}