auto与decltype
2016-09-12 20:40
253 查看
今天搜狗笔试的一道选择题,原题给忘了,但记得所考的知识点。知识点很基础,但很容易忽视。
具体内容可参考C++ Primer。
[b]auto :变量取auto后,其所对应的类型[/b]
auto一般会忽视顶层const,保留底层const。但如果将引用类型设为const,则会保留相应的顶层const。下面是C++ Primer书
中的例题,我给出了相应的标注。个人觉得比较容易犯错的地方是对常量对象取地址和对引用加auto。
View Code
decltype
这个类型写代码目前还没遇到过。它的作用是返回操作数的数据类型。
处理顶层const和引用的方式与auto不完全相同。decltype返回该变量的类型,包括顶层const和引用。
decltype和引用:
有些表达式将向decltype返回一个引用类型--当该表达式的结果对象能作为一条赋值语句的左值
decltype所用的表达式,加括号和不加括号不同。如果给变量加上一层或多层括号,编译器会把它当作表达式。而变量是一种可以
作为赋值语句左值的特殊表达式,所以这样的decltype就会得到引用类型:
另外赋值操作也是会产生引用的一种典型表达式:
auto和decltype还有一层区别是在数组上。当使用数组作为一个auto变量的初始值时,推断得到的类型为指针而非数组;
decltype不会发生上述转换。
另外再补充一点多维数组有关的知识:当用范围for语句访问多维数组时,除了最内层的循环,其他所有层的循环的控制变量都应该
是引用类型。
编译器初始化时会自动将数组转为指针,如果不是引用,row的类型就变成了int*,内层的循环就不合法了。
具体内容可参考C++ Primer。
[b]auto :变量取auto后,其所对应的类型[/b]
auto一般会忽视顶层const,保留底层const。但如果将引用类型设为const,则会保留相应的顶层const。下面是C++ Primer书
中的例题,我给出了相应的标注。个人觉得比较容易犯错的地方是对常量对象取地址和对引用加auto。
int main() { /* int i = 0, &r = i; auto a = r; const int ci = i, &cr = ci; auto b = ci; auto c = cr; auto d = &i;//指针 auto e = &ci;//对常量对象取地址是底层const const auto f = ci; auto &g = ci; //const &h = 42;错误,不能为非常量引用绑定字面值 const auto &j = 42; a = 42; b = 42; c = 42; //d = 42;错误,应为*d=42; //e=42; 错误,首先e为指针,其次e为底层const,不能修改其指向对象的值(*e=42) //可以让e指向其它对象,e=d; //g=42,错误,常量引用 */ const int i = 42; int x = 35; auto j = i; j = 35; const auto &k = i;//常量引用 //k=x;错误 auto *p = &i;//对常量对象取地址 //*p=35错误,p=&x正确 return 0; }
View Code
decltype
这个类型写代码目前还没遇到过。它的作用是返回操作数的数据类型。
处理顶层const和引用的方式与auto不完全相同。decltype返回该变量的类型,包括顶层const和引用。
const int ci = 0, &cj = ci; decltype(ci) x = 0;//const int decltype(cj)y = x;//const int & //decltype(cj) z; 错误,z是引用,必须初始化
decltype和引用:
有些表达式将向decltype返回一个引用类型--当该表达式的结果对象能作为一条赋值语句的左值
int i = 42, *p = &i, &r = i; decltype(r + 0) b;//decltype(r)返回的是引用,但r+0返回的是r所指类型 //decltype(*p) c; 这个很容易犯错,解引用指针是表达式,返回的是可以赋值的对象, //因此,c的类型是int&,而非int
decltype所用的表达式,加括号和不加括号不同。如果给变量加上一层或多层括号,编译器会把它当作表达式。而变量是一种可以
作为赋值语句左值的特殊表达式,所以这样的decltype就会得到引用类型:
decltype((i))d;错误,d为引用,必须初始化
另外赋值操作也是会产生引用的一种典型表达式:
int a = 3, b = 4; decltype(a) c = a;//c=3 decltype(a=b)d = a;//d为a的引用
auto和decltype还有一层区别是在数组上。当使用数组作为一个auto变量的初始值时,推断得到的类型为指针而非数组;
decltype不会发生上述转换。
int ia[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; auto ia2(ia);//ia2为int* 指针,指向ia的第一个元素 //ia2=42;错误,不能用int值给指针赋值 auto ia3(&ia[0]);//这两个操作等价 decltype(ia)ia4 = { 0 }; //ia4=p;错误,不能用整型指针赋给ia4 ia4[4] = 5;
另外再补充一点多维数组有关的知识:当用范围for语句访问多维数组时,除了最内层的循环,其他所有层的循环的控制变量都应该
是引用类型。
int a[3][4] = { 0 }; for (auto &row : a) { for (auto &col : row) { col = 1; } }
编译器初始化时会自动将数组转为指针,如果不是引用,row的类型就变成了int*,内层的循环就不合法了。
相关文章推荐
- Apache环境下进程检查脚本
- 装病的聚聚 codevs 5172
- 子集生成(三种办法)
- 商业化IM 客户端设计---Message模型
- 在同一台电脑上通过SSH连接不同GitHub
- TextView的基本属性
- VC操作word和excel文件,查询与读写[依赖office环境]
- 判断MAP集合中元素非空方法
- javascript 第一日(基本概念)
- 内存对齐问题
- 不能安装vm tools ,虚拟机打开了,一直是灰色的
- 2016.9.12
- iOS开发之蓝牙通信
- 解决Ubuntu安装openssh-server依赖问题
- Selenium WebDriver 中鼠标和键盘事件分析及扩展(转)
- android SharedPreferences的一般用法(存取清删)
- ExtJs教程----利用 Sencha cmd 生成应用程序
- RHEL7 的注册
- poj 2983 Is the Information Reliable?
- corosync+pacemaker实现openstack HA(一)