概述
自从C++ 11标准引入Lambda表达式以来,它已经成为现代C++编程中不可或缺的一部分,极大方便了我们的开发工作,提升了效率。而C++ 20对Lambda表达式的进一步优化和扩展,更是增强了其灵活性和实用性。
默认构造函数与赋值运算符
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;
}
???? 如果想阅读最新的文章,或者有技术问题需要交流和沟通,可搜索并关注微信公众号“希望睿智”。