C++11——string,vector,数组

使用auto或decltype作为类型缩写

Code:
    string line;
    // read input a line at a time and print lines that are longer than 80 characters
    while (getline(cin, line))
        if (line.size() > 80)
            cout << line << endl;

此处line.size()返回一个string::size_type类型的数值。
string::size_type类型是string类定义的内置类型,目的是实现代码的可移植性。使用该类型时需要添加域限制符sring::。虽然我们不知道string::size_type的确切类型,但是我们知道它是一个大小足以容纳任何字符串大小的无符号类型。用于存储string size操作结果的任何变量都应为string::size_type类型。我们在声明变量时使用string::size_type类型说明符是冗长的。新标准下,我们可以使用autodecltype来要求编译器提供适当的类型。

Code:
    auto len = line.size();   // len has type string::size_type

注:在size()表达式中不使用int,可以避免由于unsigned和int之间的转换而导致的问题。

for 范围声明(Range for Statement)

如果我们想对字符串中的每个字符执行某些操作,到目前为止,最好的方法是使用新标准引入的语句:for 范围声明。 此语句遍历给定序列中的元素,并对该序列中的每个值执行一些操作。 句法形式是:

    for (declaration: expression)
        statement

其中expression是表示序列的类型的对象,而declaration定义了我们将用于访问序列中的元素的变量。 在每次迭代中,declarationexpression中下一个元素的值初始化。
string表示一个字符序列,所以我们可以使用一个string类型的变量来作为for范围声明中的expression。举个例子,我们可以使用for范围声明来打印string类型变量中的每个字符:

Code:
    string str("some string");
    // print the characters in str one character to a line
    for (auto c : str)        // for every char in str
        cout << c << endl;    // print the current character followed by a newline

针对此处代码我们可以说按先后顺序每行打印一个str中的字符c
for范围声明是根据传统for循环的等价物来定义的:

Code:
    vector<int> v = {0,1,2,3,4,5,6,7,8,9};
    // the traditional for
    for (auto beg = v.begin(), end = v.end(); beg != end; ++beg) {
        auto &r = *beg; // r must be a reference so we can change the element
        r *= 2;         // double the value of each element in v
    }
    // the range for
    // range variable must be a reference so we can write to the elements
    for (auto &r : v)  // for each element in v
        r *= 2;        // double the value of each element in v

for范围声明简化了for循环的编写,这个新特性可以认为C++吸收了其他语言(如:Java)优秀特性的一个例子。

vector嵌套定义

早期版本C++在使用向量的向量(vector of vectors)时,声明是在两个>之间需要加入空格,而新版本中则不需要加入空格,如下所示:

Code:
    vector<vector<int> >;    // Older version about defining a vector whose elements are themselves vectors
    vector<vector<int>>;     // C++11 about defining a vector whose elements are themselves vectors

注:一些编译器可能仍然要求旧式声明

列表初始化vector

新标准下,我们可以列出初始化列表来初始化一个vector。该初始化列表由花括号及其中零个或多个元素数值组成:

Code:
    vector<string> articles = {"a", "an", "the"};  //articles consists of three elements

容器函数cbegin和cend

容器函数beginend返回的类型依赖于它们作用的对象是否是const。如果对象是const,那么beginend都返回const_iterator;如果对象不是const那么它们都返回iterator

Code:
    vector<int> v;
    const vector<int> cv;
    auto it1 = v.begin();      // it1 has type vector<int>::iterator
    auto it2 = cv.begin();     // it2 has type vector<int>::const_iterator

通常在只需要读取对象而不需要写入时,我们最好使用const类型的迭代器(如:const_iterator)。为了让我们能专门使用const_iterator类型,新标准引入了两个名为cbegincend的新函数:

Code:
    auto it3 = v.cbegin();     // it3 has type vector<int>::const_iterator

和容器函数beginend一样,cbegin返回指向第一个元素的迭代器,cend返回指向最后一个元素后一位置的迭代器。但是不论容器(如:vector或string)是否为const,它们都会返回const_iterator

库函数begin和end

虽然我们可以手动计算出数组的始末下标,但是这样做很容易出错。为了能更容易和安全地使用这类下标指针,新标准下标准库中引入了两个函数beginend。这两个函数与容器类中的成员函数beginend的行为类似。然后当我们使用数组类型时,由于数组类型不是容器类,所以针对数组类型我们往往使用库函数beginend,同时这两个函数的参数是相应的数组类型变量:

Code:
    int ia[] = {0,1,2,3,4,5,6,7,8,9};   // ia is an array of ten ints
    int *beg = begin(ia);               // pointer to the first element in ia
    int *last = end(ia);                // pointer one past the last element in ia

begin返回一个指向数组中第一个元素的指针,end返回一个指向数组中最后一个元素的后一位置的指针,这两个函数定义在头文件iterator中。

使用auto和decltype简化声明

新标准中,我们可以使用autodecltype来避免写明指向数组的指针类型,从而简化声明。

Code:
    // print the value of each element in ia, with each inner array on its own line
    // p points to an array of four ints
    for (auto p = ia; p != ia + 3; ++p) {
    // q points to the first element of an array of four ints; that is, q points to an int
        for (auto q = *p; q != *p + 4; ++q)
            cout << *q << ' ';
        cout << endl;
    }

外部for循环首先将p初始化为指向数组ia中的第一个元素。该循环一直持续到我们在ia中处理了所有三行。增量++p具有将p移动到指向ia中的下一行(即下一个元素)的效果。
内部for循环打印内部数组的值。首先使q指向p指向的数组中的第一个元素。*p操作的结果是获得含有四个整数的数组,当我们使用该数组时,它会自动转换为指向其第一个元素的指针。内部for循环一直运行到我们处理了内部数组中的每个元素。为了获得一个指向内部数组末尾的指针,我们再次解引用p以获取指向该数组中第一个元素的指针,然后我们将4添加给该指针以得到内部数组末尾的指针。
当然,我们甚至可以使用库函数beginend更容易地编写这个循环:

Code:
    // p pointsto the first array in ia
    for (auto p = begin(ia); p != end(ia); ++p) {
        // q points to the first element in an inner array
        for (auto q = begin(*p); q != end(*p); ++q)
            cout << *q << ' ';  // prints the int value to which q points
        cout << endl;
    }

这里我们使用库函数end确定结束指针,使用auto来避免写入从begin返回的类型。在外部循环中,该类型是指向含有四个int的数组的指针;在内部循环中,该类型是指向int的指针。

参考文献

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

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

推荐阅读更多精彩内容

  • 只有真的在乎了,才会去主动,等了这么久,你的一次主动,让我知道你心里一直有我。从前每天给我短信,电话聊天,真的会觉...
    大白糖宝阅读 126评论 0 3
  • 不知道有多久 我们没有手拉手 一起站在河岸边看垂柳 不知道有多久 我们没有肩并肩 一起沿着林荫路默默走 不知道有多...
    泠风思语阅读 263评论 0 7