从C++17开始,if和switch控制结构现在允许我们在条件语句或选择子句旁边指定一个初始化子句。
例如:
if (int result = getResult(); result != -1)
{
//do something
}//result 变量的有效范围到此为止。
1. 首先介绍下if判断语句中变量的初始化
在if语句中初始化的任何值在then和else部分结束之前都是有效的(如果有的话)。
例1:
#include
constexpr int defaultValue = 100;
int getValue(int i)
{
return i * 2;
}
int main()
{
if (auto result = getValue(0); result != 0)
{
std::cout << result << std::endl;
}
else
{
result = defaultValue;
std::cout << "result=" << result << std::endl;
}//result变量的有效范围到此为止
}
打印结果:
result = 100
再举另外一个列子:
例2:
std::mutex collMutex;
if (std::lock_guard lg{collMutex}; !coll.empty())
{
std::cout << coll.front() << '\n';
}
由于C++17新语法特性,我们也可以写成如下:
if (std::lock_guard lg{collMutex}; !coll.empty())//注意std::lock_guard不需要指定模板类型std::mutex了
{
std::cout << coll.front() << '\n';
}
这段代码等价于:
{//这一对大括号是为了说明lg变量的有效范围
std::lock_guard lg{collMutex};
if (!coll.empty())
{
std::cout << coll.front() << '\n';
}
}
但是要注意,在这里的初始化变量必须要有一个名字,否则,初始化的匿名变量立马就会销毁了。
列如:
if (std::lock_guard{collMutex}; // run-time ERROR:
!coll.empty()) { // 不在被lock上锁了
std::cout << coll.front() << '\n'; //不在被lock上锁了
}
if判断语句里面直接定义变量还有一个好处,有些变量的可见范围缩小了。
例3:
#include
#include
#include
打印结果:
already there: c++14, value is 2014
emplace successfully: c++17, value is 2017
按照以前的写法:
const auto result cplusplus.emplace("c++17", 2017); //result的变量在后续语句中都是可见的
if (not result.second)
{
//if c++17 exist, print the value;
const auto& elem = *(result.first);
std::cout << "already there: " << elem.first << ", value is " << elem.second << std::endl;
}
二 switch声明语句中的变量初始化
跟if的差不多,举个例子;
例4:
#include
#include
#include
namespace fs = std::filesystem;
int main()
{
std::string file_name{"switch_initialization.cpp"};
switch(fs::path p(file_name); fs::status(p).type())
{
case fs::file_type::not_found:
std::cout << p << " not found." << std::endl;
break;
case fs::file_type::directory:
std::cout << p << ":" << std::endl;
for (auto& e : fs::directory_iterator(p))
{
std::cout << "- " << e.path() << std::endl;
}
break;
default:
std::cout << p << " exists." << std::endl;
}
return 0;
}