Lambda函数(C++11起)

来自cppreference.com
< cpp‎ | language
 
 
C++语言
表达式
替代表示
字面量
布尔型 - 整型 - 浮点型
字符型 - 字符串 - nullptr (C++11)
用户定义 (C++11)
Utilities
属性 (C++11)
Types
typedef声明
类型别名声明 (C++11)
Casts
隐式类型转换 - 显示类型转换
static_cast - dynamic_cast
const_cast - reinterpret_cast
内存分配
类特有的函数属性
静态成员函数
模板
杂项
 

构造一个闭包:能在作用域内捕获变量一个的匿名函数对象。

目录

[编辑] 语法

[ capture ] ( params ) mutable exception attribute -> ret { body } (1)
[ capture ] ( params ) -> ret { body } (2)
[ capture ] ( params ) { body } (3)
[ capture ] { body } (4)

1) 完整的声明

2) 一个常lambda的声明:按副本捕获的对象不能被修改。

3) 省略后缀返回值类型:闭包的operator()的返回值类型是根据以下规则推导出的:

  • 如果body仅包含单一的return语句,那么返回值类型是返回表达式的类型(在此隐式转换之后的类型:右值到左值、数组与指针、函数到指针)
  • 否则,返回类型是void

4) 省略参数列表:函数没有参数,即参数列表是()

[编辑] 解释

mutable - 允许body修改传值进来的形参,以及调用它们的非常成员函数。
exception - 提供闭包类型的operator()成员函数的异常说明noexcept语句
attribute - 提供闭包类型的operator()成员函数的属性说明
capture - 指定哪些在函数声明处的作用域中可见的符号将在函数体内可见。

符号表可按如下规则传入:

  • [a,&b],按值捕获a,并按引用捕获b
  • [this],按值捕获了this指针
  • [&] 按引用捕获在lambda表达式所在函数的函数体中提及的全部自动储存持续性变量
  • [=] 按值捕获在lambda表达式所在函数的函数体中提及的全部自动储存持续性变量
  • [] 什么也没有捕获
params - 参数列表,与命名函数一样
ret - 返回值类型。如果不存在,它由该函数的return语句来隐式决定(或者是void,例如当它不返回任何值的时候)
body - 函数体


Lambda表达式构造唯一的匿名的非联合体非聚合体的匿名临时对象,叫做闭包型(ClosureType)。它有如下成员:

ClosureType::
原文:
ClosureType::
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
operator()(params)

ret operator()(params) const { body }
(关键字mutable没被使用)
ret operator()(params) { body }
(关键字mutable被使用)

Executes the body of the lambda-expression, when invoked. When accessing a variable, accesses its captured copy (for the entities captured by copy), or the original object (for the entities captured by reference). Unless the keyword mutable was used in the lamda-expression, the objects that were captured by copy are non-modifiable from inside this operator().

Dangling references

If an entity is captured by reference, implicitly or explicitly, and the function call operator of the closure object is invoked after the entity's lifetime has ended, undefined behavior occurs. The C++ closures do not extend the lifetimes of the captured references.

ClosureType::
原文:
ClosureType::
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
operator ret(*)(params)()

typedef ret(*F)(params);
operator F() const;

This member function is only defined if the capture list of the lambda-expression is empty.

The value returned by this conversion function is a function pointer that, when invoked, has the same effect as invoking the closure object's function call operator directly.

ClosureType::
原文:
ClosureType::
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
ClosureType()

ClosureType() = delete;
ClosureType(const ClosureType& ) = default;
ClosureType(ClosureType&& ) = default;

Closure types are not DefaultConstructible. The copy constructor and the move constructor are implicitly-declared and may be implicitly-defined according to the usual rules for implicit 拷贝构造函数 and 移动的构造函数.

ClosureType::
原文:
ClosureType::
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
operator=()

ClosureType& operator=(const ClosureType&) = delete;

Closure types are not CopyAssignable.

ClosureType::
原文:
ClosureType::
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
~ClosureType()

~ClosureType() = default;

The destructor is implicitly-declared.

ClosureType::
原文:
ClosureType::
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
CapturedParam

T1 a;

T2 b;

...

If the lambda-expression captures anything by copy (either implicitly with capture clause [=] or explicitly with a capture that does not include the character &, e.g. [a, b, c]), the closure type includes unnamed non-static data members, declared in unspecified order, that hold copies of all entities that were so captured.

The type of each data member is the type of the corresponding captured entity, except if the entity has reference type (in that case, references to functions are captured as-is, and references to objects are captured as copies of the referenced objects).

For the entities that are captured by reference (with the default capture [&] or when using the character &, e.g. [&a, &b, &c]), it is unspecified if additional data members are declared in the closure type.

[编辑] 例子

这个例子展示了(a)如何把一个lambda表达式放在通用的算法中,以及(b)lambda表达式得到的对象如何储存在std::function对象中。
原文:
This example shows how to pass a lambda to a generic algorithm and that objects resulting from a lambda declaration, can be stored in std::function objects.
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里

#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
 
int main()
{
    std::vector<int> c { 1,2,3,4,5,6,7 };
    int x = 5;
    c.erase(std::remove_if(c.begin(), c.end(), [x](int n) { return n < x; } ), c.end());
 
    std::cout << "c: ";
    for (auto i: c) {
        std::cout << i << ' ';
    }
    std::cout << '\n';
 
    std::function<int (int)> func = [](int i) { return i+4; };
    std::cout << "func: " << func(6) << '\n'; 
}

输出:

c: 5 6 7
func: 10

[编辑] 另请参阅

auto标识符 表达一个由表达式定义的一个类型(C++11) [edit]
(C++11)
包装带有指定的函数调用签名的任何类型的可调用对象
原文:
wraps callable object of any type with specified function call signature
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里

(类模板) [edit]