博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【C++11】第一篇:新关键字
阅读量:4347 次
发布时间:2019-06-07

本文共 5018 字,大约阅读时间需要 16 分钟。

auto
auto是在编译时对变量进行类型推导,从初始化表达式中推断出变量的数据类型。
如下代码
1 #include 
2 #include
3 4 using namespace std; 5 int* f() 6 { 7 int *p = new int(); 8 *p = 2; 9 10 return p;11 }12 13 int main()14 {15 auto a;16 auto i = 2;17 auto s = "hello";18 19 printf("%s %d\n", s, i);20 21 vector
vec{
1, 2, 3, 4, 5};22 23 auto it = vec.begin();24 auto end = vec.end();25 26 for (; it != end; ++it)27 {28 printf("%d ", *it);29 }30 printf("\n");31 32 auto a = f();33 auto* b = f();34 35 printf("a=%d *a= %d b=%d *b=%d\n", a, *a, b, *b);36 37 return 0;38 }

编译结果

root@yzj-VirtualBox:/home/wzw/workstation/c++11# g++ -std=c++11 test.cpp -o testtest.cpp: 在函数‘int main()’中:test.cpp:8:7: 错误:‘auto a’声明有缺少初始值设定  auto a;

第一次编译,失败。原因是auto a;没有初始化。

因为auto是通过初始化表达式进行类型推导的,所以这样的代码无法对a进行类型确定,是自动推导,但也没这么智能啊,所以该程序员做的事,还得做。
好了,把auto a;注释掉,再编译一次运行看结果吧。
root@yzj-VirtualBox:/home/wzw/workstation/c++11# g++ -std=c++11 test.cpp -o testroot@yzj-VirtualBox:/home/wzw/workstation/c++11# ./testhello 21 2 3 4 5 a=7163952 *a= 2 b=7163984 *b=2
上面的代码发现了几个
亮点呢?
1、可以不理会变量的类型,只要在定义时进行初始化,即时是指针也可以不显示的定义成auto*,同理引用、const等等也可以不显示(不过个人认为还是显示比较好,免得阅读障碍)。
2、对于STL迭代器,在auto变量引入之前我们需要vector<int>::iterator it = vec.begin();这样来定义,而现在auto it = vec.begin();不但在编码时候效率提高了,视觉上也感觉清新舒爽了很多有没有?
3、vec的初始化看到没?直接在{}中初始化,和数组的初始化一样一样的啊。这也是C++11的一个新特性,
初始化列表。此处不细说,后面再说。
其实auto的好处还不止这些,在模板中会更爽。
比如下面这个函数
1 template 
2 void BuidProduct(const Builder& builder)3 {4 Product val = builder.buildObj();5 //....6 }

使用auto变量以后可以省掉一个模板参数,不信请看。

1 template 
2 void BuidProduct(const Builder& builder)3 {4 auto val = builder.buildObj();5 //....6 }

爽不爽?不爽我们继续。

decltype 

作用和auto相反,可以从一个变量或表达式中得到类型,在有些语言中可以有Type或者getType等方法。比如说

int i = 1;decltype(i) j = 2;

下面,没有了?当然不是,请看下面。

继续说上面的模板,如果要BuildProduct需要将val返回,那返回类型怎么办呢?我们不是有auto吗?没错,有auto。但是光有auto还不行,不过你得这么干才行。

1 template 
2 auto BuidProduct(const Builder& builder) -> decltype(builder.buildObj())3 {4 auto val = builder.buildObj();5 //....6 return val;7 }

注意红色字体部分,在C++11中,可以把返回类型放在函数后面,用auto代替前面的返回类型。如果不加这句会什么效果呢?

编译结果如下:

testauto.cpp:55:41: 错误:‘BuildProduct’ function uses ‘auto’ type specifier without trailing return type

所以这是不能少滴。

nullptr

咦?我们不是有NULL了吗,还要加这么个破玩意儿干啥?注意,请注意,这不是破玩意儿。这是为了解决NULL二义性问题而加入的。因为地球人都知道NULL其实就是0。

空口无凭,有代码为证

1 #include 
2 3 using namespace std; 4 5 void f(int i) 6 { 7 cout << i << endl; 8 } 9 10 void f(int *p)11 {12 if(NULL != p)13 {14 cout << p << endl;15 }16 }17 18 int main()19 {20 int *p = nullptr;21 int *q = NULL;22 23 int a = nullptr;24 int b = NULL;25 26 f(0);27 f(nullptr);28 29 return 0;30 }

编译结果如何?你猜!

root@yzj-VirtualBox:/home/wzw/workstation/c++11# g++ -std=c++11 testnullptr.cpp -o testnullptrtestnullptr.cpp: 在函数‘int main()’中:testnullptr.cpp:23:10: 错误:不能在初始化时将‘std::nullptr_t’转换为‘int’  int a = nullptr;          ^testnullptr.cpp:24:13: 警告:将 NULL 转换到非指针类型‘int’ [-Wconversion-null]     int b = NULL;

看到没,int a = nullptr;报错,而int b = NULL;只是警告。说明啥?nullptr不能强制转换成int,而NULL可以。

f(0);这个调用,如果不是在C++11中也会编译失败,为啥?因为它有二义性,f(int)和f(int *)傻傻分不清。而在C++11中就明确的调用f(int)。

序列for循环

又一个节省编码量的特性,可以用于遍历数组、容器、string以及定义了begin、end以及iterator的自定义序列,如下列代码:

1 #include 
2 #include
3 #include
4 5 using namespace std; 6 7 int main() 8 { 9 map
m{
{
"a", 1}, {
"b", 2}, {
"c", 3}};10 11 for (auto p : m)12 {13 cout << p.first << " : " << p.second << endl;14 }15 16 return 0;17 }

清新舒爽有木有?这句话怎么像WSJ广告里面的啊?

最后回来说是初始化列表的事儿吧

我们知道,在C++11之前只有数组可以用初始化列表,而在C++11中C++11新添加初始化列表 std::initializer_list<>类型,可以通过{}语法来构造初始化列表 ,所以vector、list等容器,string以及自定义结构体、类、函数都可以使用初始化列表。请看代码
#include 
#include
#include
#include
using namespace std;void foo(initializer_list
list){ for (auto iter = list.begin(); iter != list.end(); ++iter) { cout << *iter << ", "; } cout << endl << list.size() << endl;}int main(){ foo({
1.0f, 3.7f, 8.9f}); vector
v1 = { "hello", "world", "welcome"}; vector
v2 = { 0, 3, 8, 1, 4}; unordered_map
dictionary = { { 1, "one"}, { 2, "two"}, { 3, "three"} }; for (auto i : dictionary) { cout << i.first << " -> " << i.second << endl; }}

 好了,这回下面真的没有了。

 且听下回分解。。。

转载于:https://www.cnblogs.com/zhiqli/p/3964825.html

你可能感兴趣的文章
(简单)华为Nova青春 WAS-AL00的USB调试模式在哪里开启的流程
查看>>
图论知识,博客
查看>>
[原创]一篇无关技术的小日记(仅作暂存)
查看>>
20145303刘俊谦 Exp7 网络欺诈技术防范
查看>>
原生和jQuery的ajax用法
查看>>
iOS开发播放文本
查看>>
20145202马超《java》实验5
查看>>
JQuery 事件
查看>>
main(argc,argv[])
查看>>
第四阶段 15_Linux tomcat安装与配置
查看>>
NAS 创建大文件
查看>>
学习笔记-模块之xml文件处理
查看>>
接口测试用例
查看>>
Sybase IQ导出文件的几种方式
查看>>
转:How to force a wordbreaker to be used in Sharepoint Search
查看>>
MySQL存储过程定时任务
查看>>
Python中and(逻辑与)计算法则
查看>>
POJ 3267 The Cow Lexicon(动态规划)
查看>>
设计原理+设计模式
查看>>
tomcat 7服务器跨域问题解决
查看>>