老子有钱手机版老子有钱手机版


老子有钱电话

auto类型-现代C++新特性

auto类型

C++11中引入的auto主要用于类型推导。auto在C++98中“存储类型指示符”的语义,由于使用极少且多余,该语义从C++11开始被删除。

auto类型推导用于从初始化表达式中推断出变量的数据类型,通过此方法可以有效简化代码:

Example:

//简化前的代码for (std::vector<std::string>::iterator i = vs.begin(); i != vs.end(); i++){ //code}//简化后的代码for (auto i = vs.begin(); i != vs.end(); i++){ //code}

上例中,auto能够自动推导出vs.begin()的类型,从而避免了冗长的类型说明。这个用法是我们大力推荐的。

当auto用于模板定义中,其“自适应”性会得到更充分的体现。

Example:

#include<iostream>template<typename T1, typename T2>double Sum(T1 & t1, T2 & t2) //从c++14起,也可以支持函数返回值类型设为auto,这种用法多用于编写库的开发人员。{ auto s = t1 + t2; //s的类型会在模板实例化时被推导出来 return s;}int main(){ int a = 3; long b = 5; float c = 1.0f, d = 2.3f; auto e = Sum<int, long>(a, b); //s的类型被推导为long auto f = Sum<float, float>(c, d); //s的类型被推导为float std::cout << e << " " << f << std::endl; return 0;}//编译选项:g++ -std=c++11 auto1.cpp

上例中,由于类型T1、T2要在模板实例化时才能确定,所以在Sum中将变量s的类型声明为auto。

auto可以与指针和引用结合起来使用,使用效果符合我们的想象。如下例所示:

Example:

#include<iostream>#include<typeinfo>int main(){ int x = 0; int *y = &x; auto &b = x; //int& auto c = y; //int* auto *d = y; //int* auto e = b; //int return 0;}//编译选项:g++ -std=c++11 auto2.cpp

本例中,对于c、d两个变量而言,声明其为auto*或auto并没有区别。

而如果要使得auto声明的变量是另一个变量的引用,则必须使用auto&,如本例中的变量b。而本例中e没有带&,则被推导成int类型。正如我们所熟知的,使用引用其实是使用引用的对象,特别是当引用被用作初始值时,真正参与初始化的其实是引用对象的值。

其次,auto与const和volatile之间也存在着一些相互关系。const和volatile代表了变量的两种不同的属性:易失和常量。在c++标准中,它们常常被一起叫作cv限制符(cv-qualifier)。

在深入介绍auto和cv限定符连用之前,先介绍下C++11中的顶层const和底层const。顶层const(top-level const)表示指针本身是一个常量,而底层const(low-level const)表示指针所指的对象是一个常量。

更一般的,顶层const可以表示任意的对象是常量,这一点对于任何数据类型都适用,如算术类型、类、指针等。底层const则与指针和引用等复合类型的基本类型部分有关。

int i = 0;int *const p1 = &i; //顶层constconst int ci = 42; //顶层constconst int *p2 = &ci; //底层constconst int *const p3 = p2; //右边的const是顶层const,左边的const是底层constconst int &r = ci; //用于声明引用的const都是底层const

同理,volatile与const的用法相似。

鉴于cv限制符的特殊性,C++11标准规定auto可以与cv限制符一起使用。在连用时,auto一般会忽略掉顶层const,同时底层const则会保留下来,比如当初始值时一个指向常量的指针时:

Example:

int i = 0;const int ci = i, &cr = ci;auto b = ci; //b:int(ci的顶层const特性被忽略掉了)auto c = cr; //c:int(cr是ci的别名,ci本身是顶层const)auto d = &i; //d:int *(整数的地址就是指向整数的指针)auto e = &ci; //e:const int *(对常量对象取地址是一种底层const)

如果希望推断出auto类型是一个顶层const,需要明确指出:

const auto f = ci; //ci的推演类型是int,f是const int

同理volatile与auto连用的用法和const一致。

auto在使用上的限制:以下四种情况特点基本类似,人为观察很容易能够推导出auto所在位置应有的类型,但现有标准还不支持这样的方式。

Example:

#include<vector>using namespace std;void fun(auto x = 1) //1:auto函数形参,无法通过编译{}struct str{ auto var = 10; //2:auto非静态成员变量,无法通过编译};int main(){ char x[3]; auto y = x; auto z[3] = x; //3:auto数组,无法通过编译 vector<auto> v = { 1 }; //4.auto模板参数(实例化时,)无法通过编译 return 0;}//编译选项:g++ -std=c++11 auto3.cpp, 1, 0, 9);

欢迎阅读本文章: 陈文举

老子有钱88平台

老子有钱电话