Lambda 表达式

26 篇文章 4 订阅
6 篇文章 0 订阅

简单来说,编程中提到的 lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。

Lambda表达式完整的声明格式如下:

[capture list] (params list) mutable exception-> return type { function body }

各项具体含义如下:

  • [capture list]:捕获外部变量列表,捕捉列表总是出现在Lambda函数的开始处,作为编译器判断lambda表达式的特征,这部分必须存在,不能省略。
  • (params list):形参列表可有可无 (也称为lambda声明符),就是正常的函数输入参数,没有参数时()可以省略。
  • mutable指示符:可有可无,用来说用是否可以修改捕获的变量,按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身),默认值传递为const
  • exception:表示Lambda表达式可以抛出指定类型的异常
  • ->return type:返回值类型,当返回值为void,可省略
  • { function body }:lambda 体(函数体)

Lambda 以捕获子句开头。 它指定捕获的变量以及捕获是通过值还是通过引用来捕获。 具有符号 (&)前缀的变量通过引用访问,不包含它的变量通过值访问。

空capture子句[]指示lambda表达式的主体不访问封闭范围中的变量。

可以使用捕获-默认模式来指示如何捕获 lambda 体中引用的任何外部变量:

  • [&] 表示引用的所有变量都按引用捕获
  • [=] 表示它们是通过值捕获的
  • 可以使用默认捕获模式,然后为特定变量显式指定相反的模式

例如,如果lambda体通过引用访问外部变量total并通过值访问外部变量factor,则以下capture子句等效:

[&total, factor]
[factor, &total]
[&, factor]
[factor, &]
<!--[=, &total]-->
[&total, =]

此外,我们还可以省略其中的某些成分来声明“不完整”的Lambda表达式,常见的有以下几种:

序号格式
1 省略mutable exception[capture list] (params list) -> return type {function body}
2 省略return type[capture list] (params list) {function body}
3 省略params list[capture list] {function body}

代码实例

示例1:

下面这段代码是Codec2Client::createComponent中创建component的一段:

media/codec2/hidl/client/client.cpp

mBase1_0->createComponent(
    name,
    hidlListener,
    ClientManager::getInstance(),
    [&status, component, hidlListener](
        Status s,
        const sp<hardware::media::c2::V1_0::IComponent>& c) {
        status = static_cast<c2_status_t>(s);
        if (status != C2_OK) {
            return;
        }
        *component = std::make_shared<Codec2Client::Component>(c);
        hidlListener->component = *component;
    });

capture list是:[&status, component, hidlListener],status,component,hidlListener三个是外部变量

param list是:(Status s, const sp<hardware::media::c2::V1_0::IComponent>& c)sc是形参列表,在mBase1_0->createComponent这个函数内部调用lambda表达式的时候会传入具体的参数,这里,可以把lambda表达式理解为函数指针,内部调用lambda表达式就和使用函数指针是一样的。

函数体是:

{
    status = static_cast<c2_status_t>(s);
    if (status != C2_OK) {
        return;
    }
    *component = std::make_shared<Codec2Client::Component>(c);
    hidlListener->component = *component;
}

示例2:

media/codec2/hidl/client/client.cpp

std::shared_ptr<Codec2Client::Component>
        Codec2Client::CreateComponentByName(
        const char* componentName,
        const std::shared_ptr<Listener>& listener,
        std::shared_ptr<Codec2Client>* owner,
        size_t numberOfAttempts) {
    std::string key{"create:"};
    key.append(componentName);
    std::shared_ptr<Component> component;
    
	c2_status_t status = ForAllServices(
            key,
            numberOfAttempts,
            [owner, &component, componentName, &listener](const std::shared_ptr<Codec2Client> &client)-> c2_status_t {
                c2_status_t status = client->createComponent(componentName, listener, &component);
                if (status == C2_OK) {
                    if (owner) {
                        *owner = client;
                    }
                } else if (status != C2_NOT_FOUND) {
                    // LOG ...
                }
                return status;
            });

    if (status != C2_OK) {
        // LOG ...
    }
    return component;
}

lambda表达式为:

[owner, &component, componentName, &listener](const std::shared_ptr<Codec2Client> &client)-> c2_status_t {
    c2_status_t status = client->createComponent(componentName, listener, &component);
    if (status == C2_OK) {
        if (owner) {
            *owner = client;
        }
    } else if (status != C2_NOT_FOUND) {
        // LOG ...
    }
    return status;
});

[owner, &component, componentName, &listener]是capture list

(const std::shared_ptr<Codec2Client> &client)是形参列表,参数client在ForAllServices函数中调用这个表达式的时候被传入

-> c2_status_t是返回值类型

ForAllServices函数中,第三个参数是通过std::function定义的一个函数指针,predicate是指针名,而前面的lambda和predicat类型一样,lambda表达式作为可调用对象,通过predicate调用。

c2_status_t Codec2Client::ForAllServices(
    const std::string &key,
    size_t numberOfAttempts,
    std::function<c2_status_t(const std::shared_ptr<Codec2Client>&)>predicate) {
    c2_status_t status = C2_NO_INIT;  // no IComponentStores present
    // ...
}

参考

lambda表达式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值