C++ 17 已经支持在 if 语句和 switch 语句中使用初始化的语法。
带初始化的if语句
if初始化语句中定义的变量在整个if语句范围内都是生效的。包括else if和else语句。例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| std::ofstream getLogStrm() { std::ofstream file3("c:\\x.123"); return file3; }; std::map<int,int> coll; int main() { if(std::ofstream strm = getLogStrm(); coll.empty()) { strm << "<no data>\n"; } else { for(const auto& elem : coll) { strm << elem.first << '\n'; } } return 0; }
|
如上,if语句中的strm的生命周期在执行完if语句后就被析构了,在来看下面这段代码:
1 2 3 4
| if(std::lock_guard<std::mutex> lk(mx_); v.empty()) { v.push_back(kInitialValue); }
|
上面的这段代码转换成旧式代码如下:
1 2 3 4 5
| std::lock_guard<std::mutex> lk(mx_); if(v.empty()) { v.push_back(kInitialValue); }
|
可以看出,两段代码几乎没有什么区别,唯一的差别可能是lock_guard定义的位置不一样。同样,为了让lock_guard有效,就需要给它定义一个变量。如果没有定义变量那么它在创建后就会立即被销毁。如下:
1 2 3 4
| if(std::lock_guard<std::mutex>{mx_}; v.empty()) { v.push_back(kInitialValue); }
|
上面的代码中,锁被定义后就立即被销毁,在执行后面的语句时实际上是没有加锁的。同样,在if初始化语句中也可以初始化多个变量,如:
1 2 3 4
| if(int x = qqq1(), int y = qqq2(); x != y) { std::cout << "return values " << x << " and " << y << "differ\n"; }
|
最后,还可以在if语句中对map进行插入操作,并对插入结果进行检查,代码如下:
1 2 3 4 5 6 7 8 9 10 11
| int main() { std::map<char,int> mymap; mymap.insert ({'a',100}); if(auto [pos,ok] = mymap.insert({'a',100}); !ok) { auto [key,var] = *pos; std::cout << "already there: " << key << '\n'; } return 0; }
|
带初始化的if语句
在switch语句中使用初始化语句和if中相似,如下代码,可以在switch中获取一个实例,然后根据实例的状态做不同的处理。代码如下:
1 2 3 4 5 6 7
| switch(Foo x = make_foo(); x.status()) { default: case Foo::FINE: case Foo::GOOD: case Foo::NEAT: }
|