C++11较C++03的改进

0  C++11

C++11又称为C++0x是新的C++语言的标准,发布于2011年。新的标准取代了2003年发布的C++03,也为C++带来了些许改进。

1 关键词auto修订

一门语言如果太啰嗦了,不仅会为阅读带来障碍,而且还是许多错误的根源。所以从C语言继承而来的关键词auto在C++11中有了新的定义,可以进行自动类型推断。

例如:

//  C++03 方式
for (std::vector<int>::const_iterator ci = v.begin(); ci != v.end(); ++ci);

//  C++11 方式
for (auto ci = v.cbegin(); ci != v.cend(); ++ci);
// 注意 cbegin() 和 cend() 返回一个 const_iterator

需要谨慎的一些应用。

auto x = 10.0;
// 如果将 `10.0‘ 变换为 `10‘, x 将变为一个整型变量
// 此处可能会给依赖于它的重载函数带来困扰
// 因此,建议1:利用auto消除繁琐而不是用来保持一致性

for (auto i = 0ul; i < v.size(); ++i);
// 此处 auto i = 0ul 相当于 `unsigned long int i=0‘
// 建议 2: 不要针对特定类型使用auto,因为那样做会给你带来不少问题

// 建议 3: 针对建议1和2,不要对常量使用auto

2  for()的循环范围

迭代操作在STL中是很常见的。C++11提供了一个专门的for函数来简化那些以begin()、end()为参数并返回迭代器的函数。这种新的方式对于C的数组同样有效。

例子:

// the C++03 way
for (std::vector<int>::iterator i = v.begin(); i != v.end(); ++i);

// the C++11 way
for (int &item: v);
// item 将从v的begin()执行到v的end()
// 注意这里的引用,它允许我们改变v中的内容

for (const int &item: v); // 这时不能改变内容,引用可以提速
for (int item: v); // 通过传值,不能改变v中内容

3 初始化列表

C++03中的容器不能像C中的数组那样利用列表初始化,这个问题在C++11中得到改进。

例如:

// C arrays
char   array1[] = {‘A‘, ‘B‘};
double array2[] = {32.0, 6.003, -0.1};

// C++03 vectors

std::vector<char> cpp03vector1;
cpp03vector1.push_back(‘A‘);
cpp03vector1.push_back(‘B‘);

std::vector<double> cpp03vector2(3);
cpp03vector2[0] = 32.0;
cpp03vector2[1] = 6.003;
cpp03vector2[2] = -0.1;

// C++11 vectors
std::vector<char>   cpp11vector1 = {‘A‘, ‘B‘};
std::vector<double> cpp11vector2 = {32.0, 6.003, -0.1};
// or...
std::vector<char>   cpp11vector3{‘A‘, ‘B‘};
std::vector<double> cpp11vector4{32.0, 6.003, -0.1};
// 注意这种方式也适用于STL中的其他容器, 不仅仅是std::vector

列表初始化也可以运用在更复杂的结构中,如下所示:

#include <map>
#include <string>
#include <vector>
#include <utility>

using namespace std;

map<string, vector<pair<string, int>>> name_languages_year {
    {"Dennis Ritchie",    {{"B",      1969}, {"C",        1973}}},
    {"Niklaus Wirth",     {{"Pascal", 1970}, {"Modula-2", 1973}, {"Oberon", 1986}}},
    {"Bjarne Stroustrup", {{"C++",    1983}}},
    {"Walter Bright",     {{"D",      1999}}}
};
// 注意为了匹配template  列表的嵌套方式。

cout << name_languages_year["Niklaus Wirth"].at(0).first << endl; // prints `Pascal‘

// adds a new entry to the map
name_languages_year["John McCarthy"] = {
    {"Lisp", 1958}
};
// 注意此处并没有显式的类型

4 C++数组

貌似这块儿是C++11添加的新的功能。

C++11提供了std::array,目的是来取代C中的数组。这是个尺寸可变的轻量级数组,使用的时候效果与std::vector差不多。

例子:

#include <array>

// C arrays
char  carray1[] = "Abc"; // caution, an unseen ‘\0‘ is added to the end
float carray2[] = {0.2f, 33.33f};

// C++ arrays
std::array<char, 3>  cpparray1{{‘A‘, ‘b‘, ‘c‘}};
std::array<float, 2> cpparray2{{0.2f, 33.33f}};
// 关注点 1: 尺寸在编译的时候推导
// 关注点 2:  数组尺寸不可变
// 关注点 3: 括号里的类型由参数列表决定

// 新旧数组的对比

std::cout << sizeof carray1 - 1; // -1 因为额外的 ‘\0‘
std::cout << sizeof carray2 / sizeof (float); // 元素的个数 != 字节数
std::cout << cpparray1.size();
std::cout << cpparray2.size();

carray2[-5] = 0.1f; // 下溢
cpparray2.at(-5) = 0.1f; // throws std::out_of_range 异常

//  C++ arrays 比 C arrays好的原因有很多,从上述代码可见一斑

5 少许修正

C++03中的一些小缺陷在C++11中得到了修正。

例如:

1  set<vector<int>>在C++11中可以编译了。(注意最后两个尖括号之间没有空间哦)

2  std::string 有了front和back成员函数。

3  文件流可以接受std::string类型的文件名,意味着我们不再需要使用可笑的c_str()进行转换。

4 可以很方便的将数值想std::string进行类型转换。通过以下重载函数:

   string to_string(int)

   string to_string(float)

   string to_string(double)

   ...

6 支持C++11的编译器

1 GNU C++ 编译器需要加入 -std=c++0x 来编译 C++11 代码。

2 Visual Studio 2010部分支持C++11特性。

3 Visual Studio 201X(V11)仍然只对C ++11的功能部分支持。

时间: 2024-10-06 03:43:28

C++11较C++03的改进的相关文章

[C++11 并发编程] 03 向线程传递参数

我们可以通过std::thread的构造函数向线程传递参数,但是默认情况下,这些参数的拷贝会被传递到线程内部,即使参数申明为引用,也是如此: void f(int i,std::string const& s); std::thread t(f,3,"hello"); 如上面例子所示,创建了一个线程关联到t,它会调用f(3, "hello"),虽然f的第二个参数类型为std::string,但是实际上字面量hello还是以char const *类型传递到线

[转载]如何在C++03中模拟C++11的右值引用std::move特性

本文摘自: http://adamcavendish.is-programmer.com/posts/38190.htm 引言 众所周知,C++11 的新特性中有一个非常重要的特性,那就是 rvalue reference,右值引用. 引入它的一个非常重要的原因是因为在 C++ 中,常常右值,通俗地讲"在等号右边的"临时变量或者临时对象,我们是无法得到它的修改权限的. 由于类的构造和析构机制,往往产生的临时变量或临时对象的拷贝构造及析构,会带来不少的时间.资源消耗. 也同样由于这样的限

51CTO学院新课发布~~带你遇见更好的自己(七)(2017.11.27-12.03)

以往新课发布的开场白,都是小编姐姐逗比的闲扯,小编姐姐准备转变一下画风,以后的新课发布开场白就谈谈每周我对于职场或者生活的一点小理解吧. 上周看到一篇文章,关于人和人的身价的差距:职场10年,为什么有人已经当上了董事总经理,而有的人还是资深销售经理?为什么有人已经当上了架构师,而有的人还是资深技术人员?为什么有人已经身价数十亿美金,而有的人还在为竞争总监头衔而周游于人情场?人和人的身价几倍甚至几十倍的差距,真的就只是智商.教育背景.能力.勤奋程度所决定的吗?当然不是.更大程度上是由个人的价值观.

JDK9新特性-改进进程管理 API

Java 9 这个版本对进程管理方面的改进也是相当大的.在为数不多的几次 Java 项目中,有偶尔用到多线程,但对多进程和进程方面的了解还真是太少. 我想,大部分人应该跟我一样,在编程之外知道有进程的东西的存在,在 Java 中反而会忽视,因为多线程和并发 ( Concurrency ) 的存在感更强吧. 这次 Java 9 对进程管理的改进主要是提供了 ProcessHandle 类 ProcessHandle 类 该类在 java.lang 包中,且处于 java.base 模块中. Pro

mplayer_r37356_rebuild by gcc_4.5.1 - 2016.07.11

* change the ffmpeg version from 2.5 to 2.5.11 2016.02.03* merge the libass folder from mplayer-svncheckout-20160707* update year 2016 下载地址:http://pan.baidu.com/s/1gf5A2e3

Linux2.6.11版本:classic RCU的实现

转载自:http://www.wowotech.net/kernel_synchronization/linux2-6-11-RCU.html 一.前言 无论你愿意或者不愿意,linux kernel的版本总是不断的向前推进,做为一个热衷于专研内核的工程师,最大的痛苦莫过于此:当你熟悉了一个版本的内核之后,内核已经推进到一个新的版本,你曾经熟悉的内容可能会变得陌生(这里主要说的是该模块的内部实现,实际上,内核中的每一个子系统都是会尽量保持接口API的不变).怎么应对这种变化呢?一方面,具体的实现

MYSQL基础03(日期函数)

工作中对日期的处理是经常遇到的,需求可能多种多样,因此重点介绍. 1.获取当前日期 select NOW() -- 结果:2015-10-28 22:41:11 select NOW(),SLEEP(3),NOW() -- 结果 2015-10-28 22:43:34 0 2015-10-28 22:43:34 SELECT SYSDATE(),SLEEP(3),SYSDATE() -- 结果 2015-10-28 22:46:48 0 2015-10-28 22:46:52 -- NOW()是

Beta周第7次Scrum会议(11/16)【王者荣耀交流协会】

一.小组信息 队名:王者荣耀交流协会 小组成员 队长:高远博 成员:王超,袁玥,任思佳,王磊,王玉玲,冉华 小组照片 二.开会信息 时间:2017/11/16 17:03~17:17,总计14min. 地点:东北师范大学信息科学与技术学院107教室. 立会内容 开会前一天做了什么? (1)完成技术原型:获取指定文件夹下所有文件的文件名.修改时间.文件类型等信息. 遇到的困难? (1)进度是被催着推进···· 下一步要做什么? (1)读取一个Excel 文件的详细内容(所有单元格内的具体内容).

51CTO学院新课发布~~带你遇见更好的自己(九)(2017.11.04-12.17)

新的一周新的失望,大家好,你们的毒鸡汤姐又华丽丽的上线了.今天想跟大家聊聊这个投资.为什么要说这个呢?因为最近小编的妈妈(一位三四线小城市的中年妇女),居然开始玩区域链了,这使得小编不寒而栗,毕竟我现在都没彻底搞清楚区域链.曾记得我是2014年的时候开始听说比特币,身边有买比特币的朋友也一直跟我分享他们的喜悦.因为今年比特币的大幅上涨,形成了一种投资热潮.随之而来的区域链.加密货币等等获得了更多投资者的关注.不少投资者开始寻找下一个比特币,于2011年推出的莱特币或许是其中一个备选.曾经莱特币在