C++ 20新特性之Lambda优化

时间:2024-11-02 21:07:05

概述

自从C++ 11标准引入Lambda表达式以来,它已经成为现代C++编程中不可或缺的一部分,极大方便了我们的开发工作,提升了效率。而C++ 20对Lambda表达式的进一步优化和扩展,更是增强了其灵活性和实用性。

C++ 20新特性之Lambda优化_C++ 20


默认构造函数与赋值运算符

C++ 20允许Lambda表达式拥有默认构造函数和默认赋值运算符,这就意味着,我们可以将Lambda表达式作为类的成员,或将Lambda表达式存储在容器中。

在下面的实例代码中,我们声明了一个结构体MyProcessor。它有一个成员变量process,被初始化成了一个Lambda表达式。在main函数中,我们通过proc.process调用了函数。

#include <vector>
#include <string>
#include <iostream>
using namespace std;

struct MyProcessor
{
    // 将Lambda表达式作为类的成员
    auto process = [](const string& strText) { 
        return strText.size(); };
};

int main()
{
    MyProcessor proc;
    cout << proc.process("Hello, World") << endl;
    return 0;
}


模板Lambda

C++ 20允许Lambda表达式作为模板使用,从而可以处理不同类型的参数,提升了泛型编程能力。

在下面的示例代码中,<typename T>定义了一个模板参数T。Lambda可以接受任何类型的参数,并在内部通过typeid(T)获取类型信息,从而展示出了泛型的灵活性。

#include <iostream>
using namespace std;

int main()
{
    auto pFunc = []<typename T>(T param)
    {
        cout << "type is " << typeid(T).name() << endl;
    };

    // type is int
    pFunc(42);

    // type is double
    pFunc(3.14);

    // type is char const *
    pFunc("Text");
    return 0;
}


constexpr

Lambda表达式在C++ 20中可以声明为constexpr,这意味着,如果Lambda表达式的所有操作都是constexpr友好的,那么它就可以在编译时进行评估和执行。

在下面的示例代码中,我们定义了一个名为pSquare的Lambda表达式,并使用constexpr关键字修饰。constexpr表明这个Lambda可以在编译时求值,只要它的参数也是编译时已知的。Lambda接收一个整型参数x,并返回x的平方。由于整个Lambda表达式被声明为constexpr,只要在调用它时传入的参数是编译时期已知的常量表达式,该Lambda就可以在编译时被计算。

static_assert是一个编译时断言,它用来在编译时期验证一个条件是否为真。如果条件为假,编译器会产生一个错误并停止编译。在这个例子中,static_assert检查的是pSquare(10)的结果是否等于100。由于pSquare被定义为constexpr,且在static_assert中传入的参数10是一个编译时已知的常量,因此pSquare(10)的计算将在编译时发生。实际上,它计算的是10 * 10的结果,确实等于100。所以,这个static_assert检查会通过,不会影响编译过程。

#include <iostream>
using namespace std;

int main()
{
    constexpr auto pSquare = [](int x) { return x * x; };
    // 编译时进行检查
    static_assert(pSquare(10) == 100);
    return 0;
}


初始化捕获

在C++ 20中,我们可以在捕获列表中使用初始化表达式,这使得Lambda表达式能够捕获外部变量的值或引用,并进行初始化操作。

在下面的示例代码中,第一次调用pPrint()时,输出的是y的值,即x * 2的结果132。第二次调用pPrint()时,尽管x的值已经变为99,但Lambda中捕获的y仍然是之前计算的结果132,因此输出依旧是132。

#include <iostream>
using namespace std;

int main()
{
    int x = 66;  
    auto pPrint = [&y = x * 2]() { cout << y << endl; };
    // 输出:132
    pPrint();

    // 修改外部变量x的值,不会影响Lambda中已经捕获的y
    x = 99;
    // 仍然输出:132
    pPrint();
    return 0;
}


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