文章目录
匿名函数是一种函子(functor),什么是 functor
?
According to Wikipedia, A function object or usually referred to as a functor is a construct that allows an object to be called as if it were an ordinary function.
functor
是一个函数对象,其成员函数重载了 ()
算符,因此其能够像普通函数调用一样调用其成员函数
使用functor
相比普通函数有什么优势?
One example of the advantages of using a functor over an ordinary function is that it can access the internal member variables and functions of that object.
使用functor
比普通函数的优势在于其可以访问内部成员变量(),通常这些成员变量可以用来保存上下文(context
),而使用普通函数则需要定义全局变量才可以做到。
有了functor
,为什么还需要匿名函数?
匿名函数相比显示的定义一个类并重载其()
算符,代码编写显然要简单的多,且代码可读性更强。无需繁琐的重新定义一个类。
匿名函数是如何实现的?
当我们定义一个匿名函数时,可以看成是编译器在生成代码的时候帮我们内部定义了一个类,并重载了()
算符,因此可以看成是编译器帮我做了这些工作。利用 cppinsights.io 可以查看匿名函数的实现代码
比如当值拷贝捕获时
int v = 10;
auto f = [v](){
return v + 1;
};
其对应的编译器生成代码为
int v = 10;
class __lambda_8_14
{
public:
inline /*constexpr */ int operator()() const
{
return v + 1;
}
private:
int v;
public:
__lambda_8_14(int & _v) : v{_v} {}
};
可以看到当定义一个匿名函数时,编译器为其创建了一个类,并重载了()
算符,
需要注意的是上述int operator()()
默认为const
类型,即无法在该函数中修改捕获的变量(成员变量),需要加上mutable
关键字来去除const
限制 如下
int v = 10;
auto f = [v]() mutable {
return v++;
};
再比如引用捕获
int v = 10;
auto f = [&v, a=1](){
return 0;
};
对应为
class __lambda_8_14 {
public:
inline /*constexpr */ int operator()() const
{
return 0;
}
private:
int & v;
int a;
public:
__lambda_8_14(int & _v, const int & _a) : v{_v}, a{_a}{}
};
如下为捕获的所有可选项
[] Capture nothing (or, a scorched earth strategy?)
[&] Capture any referenced variable by reference
[=] Capture any referenced variable by making a copy
[=, &foo] Capture any referenced variable by making a copy, but capture variable foo by reference
[bar] Capture bar by making a copy; don't copy anything else
[this] Capture the this pointer of the enclosing class