MacOS 玩转C++17

距离C++17发布已经半年有余,由于编译环境的问题一直无法体验到C++17的编程乐趣,趁着Mac系统更新,抢先体验一下C++17的强大之处。

1. 关联式容器遍历新方式

        C++中关联式容器一般是指如map,set等类型,此处以map为例,下面是一段C++17(11)的map的声名及初始化,下面我们来对比对dict的遍历方式的区别。

map<int, bool> dict = {{1, 2}, {2, 3}};
C++11/14遍历方式
// 兼容C++98
for (auto it = dict.cbegin(); it != dict.cend(); ++it)
{   
    cout << it->first << " " << it->second << endl;
}   

//C++11及C++14
for (auto &it : dict)
{   
    cout << it.first << " " << it.second << endl;
}   
C++17新引入的遍历方式
for (auto &[k, v] : dict)
{   
    cout << k << ' ' << v << endl;
}  
完整代码块
#include 
#include 
using namespace std;

int main()
{
    map<int, bool> dict = {{1, 2}, {2, 3}};
    // 旧方式
    for (auto it = dict.cbegin(); it != dict.cend(); ++it)
    {   
        cout << it->first << " " << it->second << endl;
    }   
    // C++11/14
    for (auto &it : dict)
    {   
        cout << it.first << " " << it.second << endl;
    }   
    // C++17
    for (auto &[k, v] : dict)
    {   
        cout << k << ' ' << v << endl;
    }   
    return 0;
}

1. if/switch块的变量初始化

考虑一个使用场景,对前面声明的dict,如果dict是否包含key=2,如果有将其value值输入。

传统写法(C++11之后)
    auto it = dict.find(2);
    if (it != dict.end())
    {   
        cout << "Nice: " << it->second << endl;
    }   

上面的写法乍看起来没有什么总是,中规中距同时兼顾了性能问题,但代码看起来不够优雅,并且it变量被声名之后在相应的代码块作用域内一直有效。有没有办法更优雅一点呢,如果不想让it生存太久,或许下面的方式是可以的:

    if (dict.find(2) != dict.end())
    {
        cout << "Nice: " << dict[2] << endl;
    }

上面的代码成功消失了it变量,但与此同时让代码性能下降了,多了一次map的查询操作。然而步入C++17之后,让事情变得更简单了,可以如此优雅的写代码了,看下面>>

    if(auto it = dict.find(2); it != dict.end())
    {
        cout << "Nice2: " << it->second << endl;
    }
    else
    {
        cout << "Fail: " << (it == dict.end()) << endl;
    }

上面的写法让it的生命周期存在于if…else…的代码块作用域内,代码块前后还可以继续使用it来定义其它类型的变量。同理switch也支持这种用法,不再一一列举;

C++17的更新可以大大提交C++的编码及阅读效率,并且使得C++这门古老的语言更加现代化,人性化。

你可能感兴趣的:(cpp)