【C++11】第一篇:新关键字

auto

auto是在编译时对变量进行类型推导,从初始化表达式中推断出变量的数据类型。

如下代码

 1 #include <stdio.h>
 2 #include <vector>
 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<int> 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 }

编译结果

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

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

因为auto是通过初始化表达式进行类型推导的,所以这样的代码无法对a进行类型确定,是自动推导,但也没这么智能啊,所以该程序员做的事,还得做。

好了,把auto a;注释掉,再编译一次运行看结果吧。

[email protected]:/home/wzw/workstation/c++11# g++ -std=c++11 test.cpp -o test
[email protected]-VirtualBox:/home/wzw/workstation/c++11# ./test
hello 2
1 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 <typename Product, typename Builder>
2 void BuidProduct(const Builder& builder)
3 {
4     Product val = builder.buildObj();
5      //....
6 }

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

1 template <typename Builder>
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 <typename Builder>
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 <iostream>
 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 }

编译结果如何?你猜!

[email protected]:/home/wzw/workstation/c++11# g++ -std=c++11 testnullptr.cpp -o testnullptr
testnullptr.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 <iostream>
 2 #include <string>
 3 #include <map>
 4
 5 using namespace std;
 6
 7 int main()
 8 {
 9      map<string, int> 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 <vector>
#include <string>
#include <unordered_map>
#include <iostream>

using namespace std;

void foo(initializer_list<float> 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<string> v1 = {"hello", "world", "welcome"};
    vector<int> v2 = {0, 3, 8, 1, 4};

    unordered_map<int, string> dictionary = {
        {1, "one"},
        {2, "two"},
        {3, "three"}
    };

    for (auto i : dictionary) {
        cout << i.first << " -> " << i.second << endl;
    }
}

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

且听下回分解。。。

时间: 2024-08-11 03:21:31

【C++11】第一篇:新关键字的相关文章

小萌新的第一篇博客

今天刚刚申请博客,写下第一篇随笔! 之前遇到许多问题,上网发现许多问题都能在这找到答案.这里也有许多的各种技术大咖分享自己的技术和经验,大咖们的帖子有得能看懂,有得看不懂,因为我还是一个小萌新,但我相信通过以后不断的学习和努力会成长起来的!如今我也成为了博客园的一员了,以后也会把自己的点点滴滴分享出来,和大家一起交流,希望博客园的大佬多多提携. 原文地址:https://www.cnblogs.com/xiaolopo/p/10308381.html

【ABAP系列】SAP ABAP7.40新语法简介第一篇

公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP7.40新语法简介第一篇 前言部分 大家可以关注我的公众号,公众号里的排版更好,阅读更舒适. 正文部分 SAP的系统不断的更新 7.40已经出来很久了,一直忙着没有更新7.40新语法内容 慢慢写点新语法的相关内容 首先说一下7.40的特点及简介 1.ABAP 7.40是AS ABAP 7.31(也称为ABAP 7.

elasticsearch技术实战——第一篇(使用篇)

为了提高搜索命中率和准确率,改善现有羸弱的搜索功能,公司决定搭建全文搜索服务.由于之前缺乏全文搜索使用经验,经过一番折腾,终于不负期望按期上线.总结了一些使用心得体会,希望对大家有所帮助.计划分三篇: 第一篇(使用篇),主要讲解基本概念.分词.数据同步.搜索API. 第二篇(配置及参数调优篇),主要围绕JVM参数调优.异常排查.安全性等方面讲解. 第三篇(倒排索引原理篇),知其然知其所以然. 一.技术选型 说到全文搜索大家肯定会想到solr和elasticsearch(以下简称es),两者都是基

U-BOOT-2016.07移植 (第一篇) 初步分析

U-BOOT-2016.07移植 (第一篇) 初步分析 目录 U-BOOT-201607移植 第一篇 初步分析 目录 编译和移植环境 更新交叉编译工具 1 下载arm-linux-gcc 443 2 安装arm-linux-gcc 443 安装环境Ubuntu 910 下载u-boot-201607并解压 分析顶层Makefile 1 找出目标依赖关系 2 总结 初次编译u-boot 1 配置 2 编译 分析u-boot启动流程 1 分析startS 2 分析crt0S 3 总结 1. 编译和移

从Hello, world开始认识IL &lt;第一篇&gt;

IL代码分析方法 Hello, world历史 .NET学习方法论 1.引言 1988年Brian W.Kernighan和Dennis M.Ritchie合著了软件史上的经典巨著<The C programming Language>,我推荐所有的程序人都有机会重温这本历史上的经典之作.从那时起,Hello, world示例就作为了几乎所有实践型程序设计书籍的开篇代码,一直延续至今,除了表达对巨人与历史的尊重,本文也以Hello, world示例作为我们扣开IL语言的起点,开始我们循序渐进的

Python全栈开发【第一篇】:初识Python

Python全栈开发[第一篇] 本节内容: Python 的种类 Python 的环境 Python 入门(解释器.编码.变量.input输入.if流程控制与缩进.while循环) if流程控制与while循环练习题 基本数据类型前引 Python 的种类 Cpython Python的官方版本,使用C语言实现,使用最为广泛,CPython实现会将源文件(py文件)转换成字节码文件(pyc文件),然后运行在Python虚拟机上. Jyhton Python的Java实现,Jython会将Pyth

耶!!!第一篇 HTML 最最最最基础之前学习的东西

今天在飘飘同学的鼓励和建议下,我终于开通了博客园博客哈哈!!!决定把新学习的一些东西的笔记记录在这里,还可以互相监督学习,互相鼓励!谁让我们都是追求进步的人呢是吧!哦吼吼吼 之前自己一直跟着视频学习了一些html,其实学习的很慢很慢(按理说如果不是跟着视频,而是就看看html代码可能学得更快,不过也可能基础不牢固.不过说实话html这东西估计也没什么基础牢不牢固而言额).刚才突发奇想去w3schools上面做了一个20道题的小test,本来以为结果会很惨没想到还行.在这分享一下答案 - W3Sc

第一篇 Replication:复制简介

本篇文章是SQL Server Replication系列的第一篇,详细内容请参考原文. 复制这个词来自拉丁语中的"replicare",意味着重复.Replication describes the process of reproducing or duplicating.Replication in SQL Server does exactly that;it reproduces or duplicates data.任何时候,你需要创建一个数据的副本,或重现该数据的变化,复

【OpenCV入门指南】第一篇 安装OpenCV

[OpenCV第一篇]安装OpenCV 本篇主要介绍怎样下载OpenCV安装程序,怎样在VS2008下安装配置OpenCV,文章最后还介绍了一个使用OpenCV的简单小样例. <OpenCV入门指南>系列文章地址:http://blog.csdn.net/morewindows/article/category/1291764 一.OpenCV的下载 能够到http://www.opencv.org.cn/index.php/Download,然后选一个较新版本号下载.我下的是V2.3.1版本