C++11 新特性 ---- 基于范围的for循环

这篇具有很好参考价值的文章主要介绍了C++11 新特性 ---- 基于范围的for循环。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

参考爱编程的大丙的教程和跟着老师的B站视频学习所做的笔记总结: 

c++11实用特性[c/c++项目开发必备技能][完整课程请关注公众号:爱编程的大丙]_哔哩哔哩_bilibili

基于范围的for循环 | 爱编程的大丙 (subingwen.cn)

1.C++11基于范围的for循环,语法格式:

for (declaration : expression) {
    // 循环体
}

declaration 表面遍历声明,在遍历过程中,当前被遍历到的元素会被存储到声明的变量中

expression 是要遍历的对象,它可以是 表达式容器数组初始化列表

🍒① 基于范围的for信用循环遍历容器,示例代码如下
// 将容器中遍历的当前元素拷贝到了声明的变量value中,因此无法对容器中的元素进行写操作
void traversal1() {
    vector<int> t{1,2,3,4,5,6};
    for(auto value : t) {
        cout<<value<<" ";
    }
    cout<<endl;
}
1 2 3 4 5 6 

 将容器中遍历的当前元素拷贝到了声明的变量value中,因此无法对容器中的元素进行写操作 

🍒②  若需要在遍历过程中修改元素的值,需要使用引用
// 若需要在遍历过程中修改元素的值,需要使用引用
void traversal2() {
    vector<int> t{1,2,3,4,5,6};
    cout<<"遍历修改之前的容器: ";
    for(auto &value : t) {
        cout<<value++<<" ";
    }
    cout << endl << "遍历修改之后的容器: ";
    for(auto &value : t) {
        cout<<value<<" ";
    }
    cout<<endl;
}
遍历修改之前的容器: 1 2 3 4 5 6 
遍历修改之后的容器: 2 3 4 5 6 7 
🍒③ 对容器的遍历过程中,如果只是读数据,不允许修改元素的值
// 对容器的遍历过程中,如果只是读数据,不允许修改元素的值,可以使用 const 定义保存元素数据的变
// 量,在定义的时候建议使用 const auto &,这样相对于const auto 效率要更高一些
void traversal3() {
    vector<int> t{1,2,3,4,5,6};
    for(const auto& value : t) {
        cout<<value<<" ";
    }
    cout<<endl;
}
1 2 3 4 5 6 

🍄【方法】:可以使用const 定义保存元素数据的变量,在定义的时候建议使用 const auto &,因为相对于 const auto 效率要更高一些。

2.使用细节

2.1 关系型容器
// 对关系型容器map的遍历:
/*
    1.使用普通的for循环方式(基于迭代器)遍历关联型容器,auto自动推导,需要使用迭代器的方式取出元素中的键值对(和指针的操作方法相同)
        it->first
        it->second
    2.使用基于范围的for循环遍历关联性容器,auto自动推导出的类型是容器中的value_type,相当于一个对组(std:pair)对象,提取键值对的方式
      如下:
        it.first
        it.second
*/
void traversal4() {
    map<int,string> m{
        {1,"heheda"},{2,"Sakura"},{3,"Luffy"}
    };

    // 1.普通的for循环方式
    for(auto it=m.begin();it!=m.end();++it) {
        cout<<"id: "<<it->first<<",name: "<<it->second<<endl;
    } 

    // 2.基于范围的for循环方式
    for(auto& it : m) {
        cout<<"id: "<<it.first<<",name: "<<it.second<<endl;
    }
}
id: 1,name: heheda
id: 2,name: Sakura
id: 3,name: Luffy
*******************
id: 1,name: heheda
id: 2,name: Sakura
id: 3,name: Luffy
🍄【总结】

🍒① 基于迭代器遍历关联型容器,auto自动推导,需要使用迭代器的方式取出元素中的键值对(和指针的操作方法相同)

  • it->first
  • it->second

🍒② 基于范围的for循环遍历关联性容器,auto自动推导出的类型是容器中的value_type,相当于一个对组(std:pair)对象提取键值对的方式如下:

  • it.first
  • it.second
2.2 元素只读

情况一:基于范围的for循环语法,内部声明一个变量的引用就可以修改遍历的表达式中的元素的值。但并不适用所有情况,对set容器来说,内部元素都是只读的,由容器的特性来决定的。因此在for循环auto& 会被视为 const auto&

// 1.不能给具有const限定类型“const int &”的变量“item”赋值
void traversal5() {
    set<int> st{1,2,3,4,5,6};
    for(auto &item:st) {
        cout<<item++<<endl; //error:Cannot assign to variable 'item' with const-qualified type 'const int &' 
    }
}

error:Cannot assign to variable 'item' with const-qualified type 'const int &'

不能给具有const限定类型“const int &”的变量“item”赋值-----(不能给常量赋值)

情况二:基于范围的for循环中,在遍历关联型容器时也会出现同样的问题,可以得到一个std::pair引用,但是我们是不能修改里边的first值的,也就是key值

// 2.item.first 是一个常量
void traversal6() {
    map<int,string> m{
        {1,"lucy"},{2,"lily"},{3,"tom"}
    };
    for(auto& item : m) {
        //error:Cannot assign to non-static data member 'first' with const-qualified type 'const int'
        cout << "id: " << item.first++ << ", name: " << item.second << endl;
    }
}

error:Cannot assign to non-static data member 'first' with const-qualified type 'const int'
错误:不能给具有const限定类型的非静态数据成员'first'赋值

对一个表达式或者容器/数组等对象,进行基于范围的for循环遍历,请问for循环对这个容器的访问频率是一次还是多次?

// 2.3 访问次数
//  对一个表达式或者容器/数组等对象,进行基于范围的for循环遍历,请问for循环对这个容器的访问频率是一次还是多次?
vector<int> v{1,2,3,4,5,6};
vector<int>& getRange() {
    cout<<"get vector range..."<<endl;
    return v;
} 

void traversal7() {
    for(auto val : getRange()) {
        cout<<val<<" ";
    }
    cout<<endl;
}

void traversal8() {
    for(auto it = getRange().begin();it!=getRange().end();++it) {
        cout<<*it<<" ";
    }
    cout<<endl;
}
get vector range...
1 2 3 4 5 6 
==========================
get vector range...
get vector range...
1 get vector range...
2 get vector range...
3 get vector range...
4 get vector range...
5 get vector range...
6 get vector range...

🍄【实验结果表明】

🍒① 函数getRange()只在第一次迭代之前被调用,得到这个容器对象之后就不会再去重新获取这个对象了,会先确定好迭代的范围,基于这个范围直接进行遍历

🍒② 相较于普通的for循环,在每次迭代的时候都需要判断是否已到了结束边界文章来源地址https://www.toymoban.com/news/detail-666467.html

到了这里,关于C++11 新特性 ---- 基于范围的for循环的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包