C++11中的新关键字:auto与decltype
来源:互联网 发布:十字锈软件 编辑:程序博客网 时间:2024/04/29 22:08
auto
C++11之前,最无用的关键字
我们知道,在C++11以前,auto关键字的作用是声明函数内的局部变量为自动的变量。也就是说,它的作用是指出当前的变量为局部变量。是不是很多余?在函数里面声明整型局部变量,直接用 int i 就可以了,几乎没有人写成“规范”的 auto int i。所以auto成为了C++11之前最无用的关键字。
但是C++11标准来了,auto以前的作法全部作废。auto在新标准中被赋予新义,被用于自动类型推断。使用它,让编译器通过初始值来替我们去推断变量的类型。显然,auto定义的变量必须赋有初始值。比如:
auto i = 0, *p = &i;//正确:i是整数,p是整形指针auto sz = 0, pi = 3.14;//错误:sz和pi的类型不一致
首先需要明确一点的是,对于引用类型,auto看到的是引用的对象,也就是说,在参与auto判断类型的是引用对象的值,而不是这个引用。但是对于指针,和引用是不一样的,auto看到的仍然是这个指针。其次,auto一般会忽略顶层const,而保留底层const。
举个例子就清楚了:
int i = 0;const int ci = i;const int &cr = ci;const int* icptr = &ci;auto b = ci;//auto是int,即 b是一个整数(ci的顶层const特性被忽略掉了)auto c = cr;//auto是int (虽然cr是底层const,但是auto看的是它实际引用的值,即ci,而ci只是顶层const)auto c1 = icptr;//auto是const int *auto d = &i;//auto是int*,d是一个整形指针,指向iauto e = &ci;//audo等价于const int*(对于常量对象取地址,得到的也是一种底层const)
所以说,如果希望auto推断出的类型具有顶层const属性,则需要手动显示指出:
int i = 0;const auto f = &i;//f的类型为 int * constf++;//error: increment of read-only variable 'f'|
对于auto手动显式指定的引用类型,如下例所示:
const int ci = 0;auto &g = ci;//auto为const int ,g具有底层const属性auto &h = 42;//error:不能为非常量引用绑定字面值auto const &j = 42;//正确:可以为常量引用绑定字面值
对于auto,还有两点要说明:
- auto 不能做为模板参数。
//1stvector<auto>* autoVector = new vector<int>;//2ndauto autoVector = new vector<int>;显然,第二个才能体现 auto 的意义和存在价值。
- auto 不能做为函数的参数类型和返回类型。
decltype
decltype就是 declared type 的缩写。如果希望表达式的类型去推导出要定义的变量的类型,但是不想用该表达式去初始化变量,那么就要用到C++11中新引入的关键字decltype了。它的作用是选择并返回操作数的数据类型。如下所示:
decltype(func()) sum = x;//sum的类型就是函数func()的返回类型编译器并不会去调用函数func(),而只是根据func的原型去得到其返回类型。
decltype处理顶层const和引用的方式与auto有些不同。如果decltype使用的表达式是一个变量,则decltype返回该变量的类型,包括顶层const和引用在内。而auto对于引用,看到的是引用指向的对象,同时忽略顶层const。
const int ci = 0,&cj = ci;decltype(ci) x = 0;//x的类型是const intdecltype(cj) y = x;//y的类型是const int&decltype(cj) z;//error:z是一个引用,但未初始化
再次强调一下,注意区别与auto的不同,对于auto来说,引用一直是作为其所指对象的同义词出现的,只有用在decltype处是个例外。
int i = 10;const int& iref = i;decltype(iref) i2ref = i;i2ref++;//error: increment of read-only reference 'i2ref'auto i3ref = iref;i3ref++;//okcout << "i = " << i << endl;cout << "i3ref = " << i3ref << endl;输出结果为:
i = 10
i3ref = 11
可以看到,i2ref的类型是const int& ,而i3ref的类型是int .
如果decltype使用的表达式不是一个变量,则decltype返回表达式结果对应的类型。如果该表达式是一个左值,则返回引用类型。表达式如果是一个右值,则返回普通类型。
注意,一个变量如果加上一个括号,就变成一个表达式了。
注意区分 ++x 与 x++。前者是左值表达式,后者是右值表达式。前者修改自身值,并返回自身;后者先创建一个临时对像,并用 x 的值赋之,后将修改 x 的值,最后返回临时对像。
左值和右值
说到左值与右值,这里需要区分一下:在C语言里面,左值可以位于赋值语句的左侧,右值则不能。
但是在C++语言中,二者的区别就没那么简单了。
- 首先,变量是左值。
- 赋值运算符得到的结果仍然是一个左值。
- 取地址运算符作用于一个左值运算对象,返回一个指向该运算对象的指针,这是一个右值。
- 内置解引用运算符、下标运算符、迭代器解引用运算符、string和vector的下标运算符的求值结果都是左值。
- 内置类型和迭代器的递增递减运算符作用于左值运算对象,其前置版本所得结果为左值,其后置版本所得结果为右值。
前导函数 ( Forwarding Function)
template<typename T1,class T2>?type? gt(T1 x, T2 y){//some codereturn x+y;}对于上述模板函数的返回类型,我们似乎可以设置为decltype(x+y),但是不幸的是,在函数开头处,还未声明x和y,它们不在作用域内。
auto func(int x, float y) -> double
也可以写为:
auto func(int x, float y) -> decltype(x+y)其中,-> double被称为后置返回odga(trailing return type)。
现在,对于刚才那个模板函数碰到的问题,有了解决方案:
template<typename T1,class T2>auto gt(T1 x, T2 y)-> decltype(x+y){//some codereturn x+y;}
- C++11中的新关键字:auto与decltype
- c++11新特性---auto 与 decltype
- C语言11中的auto和decltype
- C++11的auto和decltype关键字
- C++11之auto、decltype关键字
- C++11的auto和decltype关键字
- const auto decltype关键字
- C++11新特性之auto&decltype
- C++11中auto 关键字、nullptr关键字和decltype关键字
- C++11的auto与decltype
- auto 与decltype
- auto 与 decltype
- auto与decltype区别
- auto与decltype
- auto与decltype
- 模拟C++11的新关键字decltype
- C++11 新特性之 decltype关键字
- C++ 11 auto & decltype
- 刚学jpetstore,遇到问题今天解决了
- php 单例模式
- 收徒教授内容!
- 收集一些可以发外链的网站
- Exchange Server 2013 系列八:邮箱服务器角色DAG实战
- C++11中的新关键字:auto与decltype
- Ionic最佳实践-了解Action Sheets
- linux内存管理之mmap
- sea.js 原理解析
- 给定一个正整数,找出一个数:与其二进制表示中1的个数相同,比该数小,而且最接近
- 【练习】面向对象系列(003)——奥特曼 PK 小怪兽
- 暂存 postgreSQL\MongoDB博客
- 大话设计模式之单例模式
- Makefile 关于realpath的研究