C语言时代,for语句引入了初始化器,代码如下:
for(int i=0;i<100;++){
printf("i=%d", i );
}
这是个很大的进步,i的作用域被限定在for循环内部。
但是if语句就没有类似语法,C++98代码要做很烦人的处理,如下:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string a = "Hello World. C++";
const auto it = a.find("Hello");
if (it != string::npos)
cout << it << " Hello\n";
const auto it2 = a.find("World");
if (it2 != string::npos)
cout << it2 << " World\n";
const auto it3 = a.find("C++");
if (it3 != string::npos)
cout << it3 << " C++\n";
}
这种风格的代码见的太多了。程序员心底里最害怕的是,因为拷贝粘贴,应该写it3的地方,被错写成it2或it1。
如果想用一个变量名字,这里是行不通的,因为const变量不能被再次赋值。所以我们想了个好招,代码如下:
int main()
{
string a = "Hello World. C++";
{
const auto it = a.find("Hello");
if (it != string::npos)
cout << it << " Hello\n";
}
{
const auto it = a.find("World");
if (it != string::npos)
cout << it << " World\n";
}
{
const auto it = a.find("C++");
if (it != string::npos)
cout << it << " C++\n";
}
}
拷贝粘贴能愉快的进行了,不怕it名字漏改了,但是这段代码是多么别扭,凭空出现一堆大括号呢。为此,C++17引入if的初始化:
int main()
{
string a = "Hello World. C++";
if (const auto it = a.find("Hello"); it != string::npos)
cout << it << " Hello\n";
if (const auto it = a.find("World"); it != string::npos)
cout << it << " World\n";
if (const auto it = a.find("C++"); it != string::npos)
cout << it << " C++\n";
}
注意,初始化器后面是分号;结束。
int main()
{
int i = 0;
if ( i=1, i>0 ) { //ok 逗号表达式
//...
}
if (int i = 1, i>0) { //error 编译错误,逗号表达式中不能定义变量
//...
}
if (int i = 1; i > 0) { //ok C++17 if init
//...
}
}
应用例子:自动锁
if (std::lock_guard<std::mutex> lk(mx_); v.empty()) {
v.push_back(kInitialValue);
}
考虑对std::map的insert操作,代码如下:
int main()
{
map<int, string> myMap = { { 1,"hello" },{ 2, "world" } };
auto pp = make_pair(3, "C++");
std::pair< std::map<int,string>::iterator, bool > result = myMap.insert(pp);
if (result.second) {
cout << "insert ok. current position=" << result.first->first << "\n";
}
else {
cout << "insert fail!" << "\n";
}
}
result.first->first是什么鬼?代码无比繁琐。C++17简化代码如下:
int main()
{
map<int, string> myMap = { { 1,"hello" },{ 2, "world" } };
auto pp = make_pair(3, "C++");
if ( const auto[iter, inserted] = myMap.insert( pp ); inserted )
cout << "insert ok. current position=" << iter->first << "\n";
else
cout << "insert fail! conflict position=" << iter->first << "\n";
}
}
inserted对应一个bool变量,iter对应一个迭代器。这样就避免了上述pair套迭代器,迭代器解引用成另一个pair的繁琐思路。
原文链接: https://www.cnblogs.com/thomas76/p/8523339.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/269988
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!