C++ 20新特性之语法糖

275 阅读3分钟

概述

C++ 20中引入了一些简化编程工作的语法上的新特性,我们暂且美其名曰:“语法糖”。下面,我们将对这些“语法糖”一一进行介绍。

语法糖1:using enum

假如有一个颜色的枚举类型,其定义如下。

enum class Color
{
    Red,
    Green,
    Blue,
    Black,
    Purple
};

在C++ 20之前,如果我们想要使用这个枚举类的某个成员,通常需要像下面这样写。

Color clr = Color::Green;

在C++ 20中,引入了using enum。它提供了一种更简洁的方式来在作用域中引入枚举类型的成员,使得在使用枚举成员时,不需要再添加前缀,从而简化了代码的编写。

// 引入Color枚举的所有成员到当前作用域
using enum Color;

// 不需要再写前缀Color::
Color favoriteColor = Green;

语法糖2:Lambda的默认捕获

在 C++ 20之前,Lambda表达式的捕获子句需要显式地列出要捕获的变量(通过 [&]、[=] 或通过逐个列出变量的方式来捕获)。在C++ 20中,允许我们使用默认捕获作为捕获子句的一部分,并在需要时显式地覆盖这些默认值。

在下面的示例代码中,我们定义了一个Lambda函数,并将其赋值给pFunc。[=, &nNumber2]捕获列表中,=表示除了明确指出的nNumber2之外,其他外部变量都按值被捕获,而&nNumber2表示nNumber2按引用被捕获。mutable关键字使得Lambda内的代码可以修改按值捕获的变量副本。在Lambda函数内部,nNumber1++尝试增加按值捕获的nNumber1的副本的值。由于Lambda被声明为mutable,这个操作是允许的,但仅修改了副本,不影响外部的nNumber1。nNumber2++直接增加了按引用捕获的nNumber2的值,这会影响到外部的nNumber2。最终,nNumber1的值为66,nNumber2的值为100。

#include <iostream>
using namespace std;

int main()
{
    int nNumber1 = 66;
    int nNumber2 = 99;
    auto pFunc = [=, &nNumber2]() mutable {
        nNumber1++;
        nNumber2++;
    };

    pFunc();
    // 输出:66
    cout << nNumber1 << endl;
    // 输出:100
    cout << nNumber2 << endl;
    return 0;
}

语法糖3:requires关键字

C++ 20中引入了requires关键字,它是约束和概念特性的核心组成部分。通过使用requires,我们可以定义一个条件。该条件必须为真,以便模板参数或函数参数满足特定的要求。这有助于在编译时捕获错误,提高代码的可读性和可维护性。

#include <iostream>
#include <concepts>
using namespace std;

// requires后面的大括号内声明了对类型T的要求,即类型T的两个实例必须能够相加
template <typename T>
concept Addable = requires(T a, T b)
{
    a + b;
};

template <Addable T>
T Add(T x, T y)
{
    return x + y;
}

int main()
{
    // 由于整型支持加法,故下面的调用是合法的
    cout << Add(66, 99) << endl;

    // 如果尝试使用不支持加法操作的类型,则编译会报错
    // cout << Add("Hello", "Hope") << endl;
    return 0;
}

语法糖4:常用的数学常量

C++ 20通过头文件引入了一系列的数学常量,这些常量提供了精确的浮点数表示,使得在需要高精度的场景下非常有用。

#include <iostream>
#include <numbers>
using namespace std;

int main()
{
    // 圆周率
    cout << numbers::pi_v<double> << endl;

    // 自然对数的底
    cout << numbers::e_v<double> << endl;

    // 黄金比例
    cout << numbers::phi_v<double> << endl;

    // 2的对数的倒数
    cout << numbers::log2e_v<double> << endl;

    // 10的对数的倒数
    cout << numbers::log10e_v<double> << endl;
    return 0;
}

💡 如果想阅读最新的文章,或者有技术问题需要交流和沟通,可搜索并关注微信公众号“希望睿智”。