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 是一个 int 左值,用于 2 位位字段

    // b 是一个 const volatile double 左值

3. 使用直接列表初始化枚举

在 C++17 中,枚举现在可以使用大括号进行初始化。

语法:

enum byte : unsigned char {};
byte b0 {0}; // OK
byte b1 = byte{1}; // OK
byte b2 = byte{256}; // ERROR - 0 to 255 only

4. 在 if 和 switch 中声明变量

C++17 允许在 if 和 switch 条件中声明变量。这使得使用具有不同作用域的相同名称的变量变得更容易。

语法:

if (data type variable condition)
{
   //statements
}
switch ( condition; variable )
{
   //statements
}

5. if constexpr 语句

对于模板代码非常有用的特性。if constexpr 语句在编译时进行评估。

它是如何工作的

可以使用下面的比较来展示它的帮助:

一般的 if-else 语句:

int var = 10;
if (var >= 10) {
   var=var+10;
} else {
   var=var-10;
}

constexpr if-else 语句:

template <typename T>
auto length ( T const& value ) { 
   //checking if T is integer or not
   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 {
      ..........
}; }

更新于:2021年10月22日

893 次浏览

开启你的职业生涯

完成课程获得认证

开始学习
广告
© . All rights reserved.