C++17 的新特性
C++ 标准委员会始终致力于每三年发布一次新特性。该规范的两个主要部分是编程语言的核心功能和标准模板库 (STL)。引入这些新特性是为了使代码更简洁、更易用、更紧凑。以下是新引入特性的列表:
1. 折叠表达式
折叠表达式用于为可变数量的参数编写更短的代码,这些参数可以传递给函数或从函数返回。它允许使用任意数量的变量作为函数的参数和返回语句。
语法:
一元右折叠 - ( pack op1 ... )
一元左折叠 - ( … op1 pack )
二元左折叠 - ( init op1 … op1 pack )
二元右折叠 - ( pack op1 … op1 init )
这里 pack 是一个参数包,可以扩展为任意数量的变量。op1 是一个运算符。 (-、+、<=、>=、<、>、==、*、/……)。在二元折叠中,两个 op1 是相同的运算符。
init 是一个无法展开的表达式。
示例
#include <iostream> #include <string> using namespace std; template<typename ...Args> auto addition(Args ...args){ return (args + ... + 0); } template<typename ...Args> auto sum2(Args ...args){ return (args + ...); } int main(){ cout << "Sum is : "<<addition(1,1,1,1,1) << endl; cout << "Sum 2 is : "<<addition ( 1,2,3); }
输出
Sum is : 5 Sum 2 is : 6
2. 结构绑定
这些用于声明多个变量,并使用对、元组等中的值进行初始化。所有这些变量与初始化器的绑定都在一个语句中完成。
情况 1:绑定数组
标识符列表中的每个标识符都将成为数组元素左值的名称。元素数量必须等于标识符数量。
int arry[3] = { 3,4,5 };
auto [a,b,c] = arry;
//此处创建数组,a 指向 3,b 指向 4,c 指向 5。
情况 2:绑定类似元组的类型
float fnum{};
char ch1{};
int number{};
std::tuple < float&, char&&, int > tplex( fnum, std::move(ch1) , number);
const auto& [ p, q, r] = tplex;
// p 是指向 fnum 的结构化绑定的名称
// q 是指向 ch1 的结构化绑定的名称
// r 是指向 number 的结构化绑定的名称
情况 3:绑定到数据成员
struct structVar {
mutable int num1 : 2;
volatile double num2;
};
structVar func();
const auto [ a, b] = func();
// a 是 2 位位字段的 int 左值
// b 是 const volatile double 左值
3.使用直接列表初始化枚举
在 C++17 中,现在可以使用大括号初始化枚举。
语法:-
枚举字节:无符号字符 {}; 字节 b0 {0}; // 正确 字节 b1 = 字节{1}; // 正确 字节 b2 = 字节{256}; // 错误 - 仅限 0 到 255
4. 在 If 和 Switch 条件中声明变量
C++17 允许在 if 和 switch 条件中声明变量。这使得使用具有不同作用域的同名变量变得更容易。
语法:-
if (data type variable condition) { //语句 } switch ( condition; variable ) { //语句 }
5. If constexpr 语句
模板代码的实用功能。if constexpr 语句在编译时进行求值。
其作用
以下比较结果可显示其实用性:-
常用 If-else 语句:-
int var = 10; if (var >= 10) { var=var+10; } else { var=var-10; }
Constexpr If-else 语句:-
templateauto length ( T const& value ) { //检查 T 是否为整数 if (is_integral<T>::value) { return value; } else { return value.length(); } }
6. 嵌套命名空间
命名空间用于将相似的代码(例如相关的类和函数)组合在一起。C++17 允许更轻松地使用嵌套命名空间的语法。以前,当嵌套命名空间的数量较多时,语法会变得相当混乱。现在不再需要处理括号。
C++17 之前:
namespace Earth{ namespace Continent { namespace Country { class City { .......... }; } } }
新语法:-
namespace Earth :: Continent :: Country { class City { .......... }; }