C++17 if/switch语句初始化
400 Words | Read in about 2 Min | View times
Overview
C++17引入了if
/switch
语句初始化的新特性,既解决了变量命名问题,也可使声明变量的作用域缩小。这一新特性还可以作用于结构化绑定。本节内容主要介绍if
/switch
语句初始化的使用。
本系列文章将包括以下领域:
本章其他内容请见 《现代C++》
什么是if/switch语句初始化
在C++17之前,一段if-else
段落或switch
段落的基本形式都是如下这种形式:
1variable-init-statement //if中使用的变量的初始化语句
2if (condition) { //对前面声明的变量进行判断
3 //...
4} else {
5 //...
6}
7
8variable-init-statement //switch中使用的变量的初始化语句
9switch (condition) {
10default:
11 break;
12}
可以看出,两处初始化语句必须使用不同的变量名,可能导致变量命名词穷,尤其在获取迭代器的代码中比较显著。
另外两处初始化语句将处于一个单独的作用域,即暴露在if
和switch
所在的作用域之外。当然也可以这样书写,但还是不方便:
1{
2 variable-init-statement
3 if (condition) {
4 //...
5 } else {
6 //...
7 }
8}
9
10{
11 variable-init-statement
12 switch (condition) {
13 default:
14 break;
15 }
16}
从C++17开始,可以通过如下的语法解决了上述问题:
1if (init; condition) {
2 //...
3} else {
4 //...
5}
6
7switch(init; condition) {
8default:
9 break;
10}
命名困难
我们前面提到if
/switch
语句初始化可以解决命名困难,常见的场景是获取STL容器的迭代器时:
1int main() {
2 std::map<std::string, int> mp {
3 {"hello", 0}, {"zhxilin", 1}
4 };
5
6 //C++17之前
7 auto itr = mp.find("hello");
8 if (itr != mp.end())
9 std::cout << itr->first << ", " << itr->second << std::endl;
10
11 auto itr2 = mp.find("zhxilin");
12 if (itr2 != mp.end())
13 std::cout << itr2->first << ", " << itr2->second << std::endl;
14
15 return 0;
16}
作用域逃逸
传统的写法初始化声明的语句的作用域要比if-else
和switch
的作用域要大,不利于管理:
1int main() {
2 std::map<std::string, int> mp {
3 {"hello", 0}, {"zhxilin", 1}
4 };
5
6 //C++17之前解决作用域逃逸的方式,顺带解决了命名困难的问题
7 {
8 auto itr = mp.find("hello");
9 if (itr != mp.end())
10 std::cout << itr->first << ", " << itr->second << std::endl;
11 }
12
13 {
14 auto itr = mp.find("zhxilin");
15 if (itr != mp.end())
16 std::cout << itr->first << ", " << itr->second << std::endl;
17 }
18
19 return 0;
20}
if/switch语句初始化
因此,C++17提供的if
/switch
语句初始化语法糖,可以一举解决上面两个问题,并使代码更加精炼:
1int main() {
2 std::map<std::string, int> mp {
3 {"hello", 0}, {"zhxilin", 1}
4 };
5
6 //C++17
7 if (const auto itr = mp.find("hello"); itr != mp.end())
8 std::cout << itr->first << ", " << itr->second << std::endl;
9
10 if (const auto itr = mp.find("zhxilin"); itr != mp.end())
11 std::cout << itr->first << ", " << itr->second << std::endl;
12
13 return 0;
14}
既限定了作用域,也可以在各自的作用域内使用相同的变量名。
与结构化绑定结合
if
/switch
语句初始化还可以在结构化绑定中使用:
1int main() {
2 std::map<std::string, int> mp;
3
4 if (auto [itr, inserted] = mp.insert({"zhxilin", 1}); inserted)
5 std::cout << itr->first << ", " << itr->second << std::endl;
6
7 return 0;
8}
可以设想一下,C++17之前这段代码需要更长的代码才能完成。
以上,就是C++17的新特性——if
/switch
语句初始化。