C++11——顺序容器

forward_list和array容器

新标准添加了forward_listarray容器。array容器是内置数组的一种更安全更易于使用的替代方法。与内置数组一样,标准库提供的array容器有固定大小。因此array容器不支持添加和删除元素或调整容器大小的操作。forward_list容器是具有最佳性能的手写单链表的替代。因此forward_list容器不支持size操作,因为与最佳性能的手写单列表相比,存储或计算其大小会产生开销。对于标准库中其他容器,size操作保证是快速,常量时间操作。
新的标准库容器比以前的版本快得多。可以肯定的是标准库容器通常表现得比最精心设计的替代品要好。现代C ++程序应该使用标准库容器而不是像数组这样的更原始的结构。
关于array容器更详细的信息可参考header <array>
关于forward_list容器更详细的信息可参考header <forward_list>

容器的cbegin和cend函数

新标准中引入了容器的cbegincend函数,用于返回const型的迭代器。同时新标准下可以使用auto声明,这也简化了具体类型的声明。而之前版本中,在声明迭代器时我们必须明确指明具体的迭代器类型。

Code:
    // type is explicitly specified
    list<string>::iterator it5 = a.begin();
    list<string>::const_iterator it6 = a.begin();
    // iterator or const_iterator depending on a's type of a
    auto it7 = a.begin();    // const_iterator only if a is const
    auto it8 = a.cbegin();   // it8 is const_iterator

autobeginend一起使用时,我们得到的迭代器类型取决于容器类型。而使用cbegincend时无论容器的类型如何都会得到const_iterator
注:当不需要对容器元素进行写操作时,我们应该使用cbegin和cend。

容器的初始化器列表

新标准下,我们可以使用初始化器列表来初始化容器。

Code:
    // each container has three elements, initialized from the given initializers
    list<string> authors = {"Milton", "Shakespeare", "Austen"};
    vector<const char*> articles = {"a", "an", "the"};

当我们这样做时,我们明确指定了容器中每个元素的值。对于除数组以外的容器类型,初始化器列表还隐式指定了容器的大小:容器将具有与初始化器列表一样多的元素

非容器成员函数swap

新标准下的标准库中,容器提供了成员和非成员版本的swap函数。标准库的早期版本仅定义了swap函数的成员版本。非成员交换在通用程序中极为重要。作为习惯,我们最好使用非成员版本的swap函数。

Code:
    vector<string> svec1(10);   // vector with ten elements
    vector<string> svec2(24);   // vector with 24 elements
    swap(svec1, svec2);

运行swap函数之后,svec1包含24个字符串元素,svec2包含10个。除了数组之外,为了保证交换两个容器能最快完成,swap函数不会交换元素本身,而是交换数据的内部结构。
除了数组,swap不会复制,删除或插入任何元素,并保证在常数时间内完成。

容器成员insert的返回类型

新标准下,带有计数或范围的insert版本将返回指向被插入的第一个元素的迭代器(而标准库的之前版本中,这样的操作将返回void)。如果传给insert的范围为空,则不插入任何元素,并且insert将返回其第一个参数

Code:
    list<string> lst;
    list<string> lnd;
    auto iter = lst.begin();
    while (cin >> word)
        iter = lst.insert(iter, word);   // same as calling push_front
    auto iter2 = lnd.insert(lnd.begin(), 2, "world");
    // iter2 point the first "world" in lnd

容器成员emplace

新标准引入了三个新成员——emplace_frontemplaceemplace_back,并且它们执行时是构造而不是复制元素。这些操作对应于push_frontinsertpush_back操作,因为它们允许我们将元素分别放在容器的前面,给定位置的前面或容器的后面。
当我们调用pushinsert成员时,我们传递元素类型的对象,并将这些对象复制到容器中。当我们调用一个emplace成员时,我们将参数传递给元素类型的构造函数。emplace成员使用这些参数直接在容器管理的空间中构造元素。下面代码中我们假定c对象是一个包含类Sales_data元素的容器。

Code:
    // construct a Sales_data object at the end of c
    // uses the three-argument Sales_data constructor
    c.emplace_back("978-0590353403", 25, 15.99);
    // error: there is no version of push_back that takes three arguments
    c.push_back("978-0590353403", 25, 15.99);
    // ok: we create a temporary Sales_data object to pass to push_back
    c.push_back(Sales_data("978-0590353403", 25, 15.99));

emplace_back的调用和对push_back的第二次调用都创建了新的Sales_data对象。在对emplace_back的调用中,该对象直接在容器管理的空间中创建。对push_back的调用会创建一个传送到容器上的本地临时对象。
emplace函数的参数因元素类型而异。参数必须与元素类型的构造函数匹配:

Code:
    // iter refers to an element in c, which holds Sales_data elements
    c.emplace_back();   // uses the Sales_data default constructor
    c.emplace(iter, "999-999999999");   // uses Sales_data(string)
    // uses the Sales_data constructor that takes an ISBN, a count, and a price
    c.emplace_front("978-0590353403", 25, 15.99);

注:emplace函数构造容器中的元素。这些函数的参数必须与元素类型的构造函数匹配。

shrink_to_fit

在新标准下,我们可以使用shrink_to_fit来请求dequevectorstring返回不需要的内存。 此功能表明我们不再需要任何多余的容量。我们无法保证调用shrink_to_fit将返回内存。
shrink_to_fit仅仅对dequevectorstring有效;capacityreserve仅仅对vectorstring有效。

Code:
    c.shrink_to_fit();  // request to reduce capacity() to equal size()
    c.capacity();       // number of elements c can have before reallocation is necessary
    c.reserve(n);       // allocate space for a least n elements

字符串的数字转换函数

新标准引入了几个在数字数据和标准库字符串之间进行转换的函数:

    int i = 42;
    string s = to_string(i);  // converts the int i to its character representation
    double d = stod(s);       // converts the string s to floating-point

字符串与数字数据之间的转换如下表所示:

函数 功能
to_string(val); 重载函数。返回val的字符串表示形式。val可以是任何算术类型。对于每一种浮点数类型、int或更大的整数类型,都有对应版本的to_string
stoi(s, p, b);
stol(s, p, b);
stoul(s, p, b);
stoll(s, p, b);
stoull(s,p,b);
返回具有类型int, long, unsigned long, long long, unsigned long long的数字内容的s的初始子字符串。b表示用于转换的数字基数;b默认为10。p是指向size_t的指针,在该指针中保存s中第一个非数字字符的索引。
stof(s, p);
stod(s, p);
stold(s, p);
返回具有类型float, double, long double的数字内容的s的初始子字符串。p的作用与整形转换函数中p的作用相同。

字符串中我们能转换成数字的第一个非空格字符一定是可以在数字中出现的字符。

Code:
    string s2 = "pi = 3.14";
    // convert the first substring in s that starts with a digit,  d = 3.14
    d = stod(s2.substr(s2.find_first_of("+-.0123456789")));

上述代码中我们首先调用find_first_of函数来找到字符串中第一个可以是数字的一部分的字符。我们将从find_first_of返回位置处开始的子串传给stodstod函数读取这个字符串直到遇到一个不能是数字的一部分的字符为止,然后将其转换为双精度的浮点数。
字符串中的第一个非空白字符必须是符号(+或 -)或数字。字符串可以以0x0X开头,表示十六进制。对于转换为浮点的函数,字符串也可以以小数点(.)开头,并且可以包含e或E来指定指数。对于转换为整数类型的函数,根据基数,字符串可以包含与数字9之外的数字相对应的字母字符。
注:如果字符串无法转换为数字,则这些函数会抛出invalid_argument异常。如果转换生成的值无法表示,则会抛出out_of_range

参考文献

[1] Lippman S B , Josée Lajoie, Moo B E . C++ Primer (5th Edition)[J]. 2013.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349