主要聊一下 C++17,顺便记录一下 RAII。说句真心话,只要 C++ 遵照最佳实践来编码,还是很省心的,就算它有很多丑陋的地方,你不用它,不看它不就完了。
C++17的一些特性
在if/switch中初始化变量
#include <iostream>
int main(void)
{
if (auto i = 42; i > 0) {
std::cout << "Hello World\n";
}
}
可以保证变量是有效的。
#include <iostream>
int main(void)
{
switch(auto i = 42) {
case 42:
std::cout << "Hello World\n";
break;
default:
break;
}
}
编译时优化
下面代码运行时会优化(移除)if
分支。
#include <iostream>
constexpr const auto val = true;
int main(void)
{
if (val) {
std::cout << "Hello World\n";
}
}
constexpr
在 C++11 时就引入了,但是很多程序员都假定会优化分支,其实并没有。
C++17 还引入了 constexpr if
,如果编译时不能优化 if
将会报错。
#include <iostream>
int main(void)
{
if constexpr (constexpr const auto i = 42; i > 0) {
std::cout << "Hello World\n";
}
}
C++11 中就有这样的断言,
#include <iostream>
int main(void)
{
static_assert(42 == 42, "the answer");
}
C++17 引入了一个新的形式,可以直接这样使用:
#include <iostream>
int main(void)
{
static_assert(42 == 42);
}
命名空间
C++17 添加了嵌套命名空间,不再需要换行。在C++17之前,嵌套命名空间需要这样写:
#include <iostream>
namespace X
{
namespace Y
{
namespace Z
{
auto msg = "Hello World\n";
}
}
}
int main(void)
{
std::cout << X::Y::Z::msg;
}
C++17可以把它写到同一行中:
#include <iostream>
namespace X::Y::Z
{
auto msg = "Hello World\n";
}
int main(void)
{
std::cout << X::Y::Z::msg;
}
结构化绑定
这是很多人最喜欢的 C++17 的新特性。在 C++17 以前,复杂的结构,比如结构体或者 std::pair
,可以用于返回值不止一个的函数。但它的语法非常笨重。就像这样:
#include <utility>
#include <iostream>
std::pair<const char*, int>
give_me_a_pair()
{
return {
"The answer is:", 42};
}
int main(void)
{
auto p = give_me_a_pair();
std::cout << std::get<0>(p) << std::get<1>(p) << '\n';
}
在 C++17,结构化绑定(structed bindings)提供了一种将 struct 或者 std::pair
解析独立字段的方法。
#include <utility>
#include <iostream>
std::pair<const char*, int>
give_me_a_pair()
{
return {
"The answer is:", 42};
}
int main(void)
{
auto [msg, answer] = give_me_a_pair();
std::cout << msg << answer << '\n';
}
同样,可以用于 struct。
#include <iostream>
struct mystruct
{
const char *msg;
int answer;
};
mystruct
give_me_a_struct()
{
return {
"The answer is:", 42};
}
int main(void)
{
auto [msg, answer] = give_me_a_struct();
std::cout << msg << answer << '\n';
}
内联变量
C++17 一个比较有争议的添加就是内联变量。因为现在有很多库只有头文件,也就是把实现也写在了头文件中。可这也意味着会引入全局变量,那么就可能与正在编写的代码冲突。
内联变量移除了这个问题,就像这样:
#include <iostream>
inline auto msg =