让我们从Lambda表达式开始本周。我们的计划是编写一组简明的文章,介绍lambda表达式的核心元素。今天,您可以看到自C++11以来语法是如何演变的,以及C++20中的最新变化是什么。
()-参数列表,与常规函数一样,如果说明符/异常列表为空,则为可选。
RET结尾的返回类型,大多数情况下不需要,因为编译器可以推导出该类型。
您可以阅读位于N3337-C++11的最终草案:[expr.prim.lambda]下的规范。
//1.最简单的lambda:[]{};//2.带两个参数:[](Float f,int a){return a*f;};[](int a,int b){return a<;b;};//3.尾随返回类型:[](MyClass T)->;int{auto a=t.computer();print(A);return a;};//4.其他说明符:[X](int a,int b)可变{++x;return a<;b;};[](浮动参数)noExcept{return param*param;};[x](int a,int b)可变noExcept{++x;return a<;b;};//5.可选()[x]{std::cout<;<;x;};//no()是否需要[x。//Won&39;t编译![X]()可变的{++x;};//在可变的[]noExcept{};//Won';t COMPILE![]()NoExcept{};//FINE之前需要FINE-()。
在C++14中,“高级”语法没有太大改变,但是CAPTURE子句允许您执行“使用初始化器捕获”,并且参数列表可以接受自动参数(这意味着泛型lambdas)。
此外,lambda表达式的返回类型遵循常规函数返回类型演绎(AUTO)的规则,因此简而言之,编译器现在更聪明了。
#include<;iostream>;int main(){int x=30;int y=12;const auto foo=[z=x+y](){std::cout<;<;z<;';\n';;};x=0;y=0;foo();}
正如您在上面看到的,编译器现在可以从z=x+y这样的表达式创建闭包类型的成员变量。
()-参数列表,与常规函数一样,如果说明符/异常列表为空,则为可选。
Conexpr auto Square=[](Int N){return n*n;};//隐式conexpr static_assert(Square(2)==4);
Struct Baz{auto foo(){return[*this]{std::cout<;<;s<;<;std::Endl;};}std::String s;};
另一件要记住的事情是,在C++17中删除了动态异常规范,因此在实践中,您只能使用noexclude来标记函数和lambdas。
从C++20开始,您现在可以使用consteval作为lambda的附加说明符,而且,您还可以指定模板尾部!
()-参数列表,与常规函数一样,如果说明符/异常列表为空,则为可选。
Int main(){const int x=10;auto lam=[](Int X)consteval{return x+x;};return lam(X);}
在下一篇文章中,您将了解如何从外部作用域捕获内容。请看这里:TODO,明天:)。
如果你想知道更多,你可以看我关于λ的书!以下是如何获得它并加入1000名读者的选择:
与我的C++17一起购买图书购买C++17详细信息和C++Lambda故事一起购买