最近在学习安卓播放的omx的代码,在allocateNode的时候发现有个函数很奇怪:
status_t LWOmx::allocateNode(
char const* name,
sp const& observer,
sp* omxNode) {
status_t fnStatus;
status_t transStatus = toStatusT(mBase->allocateNode(
name, new TWOmxObserver(observer),
[&fnStatus, omxNode](Status status, sp const& node) {
fnStatus = toStatusT(status);
*omxNode = new LWOmxNode(node); // 这块是啥?
}));
return transStatus == NO_ERROR ? fnStatus : transStatus;
}
Return Omx::allocateNode(const hidl_string& name, const sp& observer, allocateNode_cb _hidl_cb) {
......
_hidl_cb(toStatus(OK), new TWOmxNode(instance));
return Void();
}
[&fnStatus, omxNode](Status status, sp
本着一颗热爱学习的心,我研究(度)了一下。
原来这个东东就是c++11中的新功能: 匿名函数(lambda表达式)
所以呢?啥叫匿名函数?别着急,继续往下看。
顾名思义: 匿名函数, 就是定义时未直接指定名称的函数.
匿名函数有啥优点呢?
非匿名函数在定义时,就已经创建函数对象和作用域对象;所以,即使未调用,也占用内存空间;
匿名函数,仅在调用时,才临时创建函数对象和作用域链对象;调用完,立即释放,所以匿名函数比非匿名函数更节省内存空间.
匿名函数表达式格式如下:
[capture] (parameters) mutable exception attribute -> return_type { body }
必须用方括号括起来的capture列表来开始一个lambda表达式的定义。
如果函数体只有一个return語句,或者返回值类型为void,那么返回值类型声明(capture)可以被省略:
lambda函数的使用场景1:
std::vector some_list{ 1, 2, 3, 4, 5 };
int total = 0;
std::for_each(begin(some_list), end(some_list), [&total](int x) { total += x; });
// 这里[&total](int x) { total += x; }就是lambda函数。total就表示list中所有元素只和。
看到这里,估计又有人问,for_each是个啥?
for_each也是c++11的新功能,大概看一下:
template
Function for_each(InputIterator beg, InputIterator end, Function f) {
while(beg != end)
f(*beg++);
}
看到这里就比较清晰了,上面对lambda的应用实际就是把some_list中的元素逐个当做参数传给lambda函数,然后把所有元素加起来。
lambda函数的使用场景2:
#include
#include
#include
double eval(std::function f, double x = 2.0)
{
return f(x);
}
int main()
{
std::function f0 = [](double x){return 1;};
auto f1 = [](double x){return x;};
decltype(f0) fa[3] = {f0,f1,[](double x){return x*x;}};
std::vector fv = {f0,f1};
fv.push_back ([](double x){return x*x;});
for(auto &f : fv)
std::cout << "fv: " << f(2.0) << std::endl;
for(auto &f : fa)
std::cout << "fa: " << f(2.0) << std::endl;
std::cout << "eval(f0): " << eval(f0) << std::endl;
std::cout << "eval(f1): " << eval(f1) << std::endl;
std::cout << "eval([]): " << eval([](double x){return x*x;}) << std::endl;
return 0;
}
运行结果:
fv: 1
fv: 2
fv: 4
eval(f0): 1
eval(f1): 2
eval([]): 4
这里其他几个都好理解,我们看看最后一个eval([](double x){return x*x;}) ,这里首先是函数eval,他的第一个参数是一个函数,这个函数的定义在调用eval的地方,也就是[](double x){return x*x;},所以,调用eval([](double x){return x*x;} 就是把eval第二个参数double x赋值给第一个参数(函数f)的形参x,然后对x求平方并返回。
了解了这些之后,我们再来看omx里面allocateNode函数的意思:
阴影部分就是lambda函数的的定义。
_hidl_cb(toStatus(OK), new TWOmxNode(instance));
这里是对lambda函数的调用,实际就是把toStatus(OK)赋值给上面的Status status,把new TWOmxNode(instance)赋值给sp
emmm……到这里就全部结束了,下班回家~