C++语言中的可调用对象可分为:函数、函数指针、lambda表达式、bind创建的对象和重载了函数调用运算符(重载()运算符)的类
1、lambda
lambda表达式形式如下:
[捕获列表](参数列表) -> 返回类型 {函数体}
其中参数列表和返回类都可以忽略。
捕获列表
捕获列表分为值捕获,引用捕获和隐式捕获
(1)值捕获
int main()
{
int a = 30;
auto f = [a] { return a; };
a = 0;
auto j = f();
cout << j << endl;//j为30
return 0;
}
值捕获不能修改变量的值,想修改变量的值必须在参数列表后加上mutable关键字。
int main()
{
int a = 30;
auto f = [a]() mutable { return ++a; };
a = 0;
auto j = f();
cout << j << endl;//j为31
return 0;
}
(2)引用捕获
引用捕获可以修改变量得值
int main()
{
int a = 30;
auto f = [&a] { return a; };
a = 0;
auto j = f();
cout << j << endl;//j为0
return 0;
}
(3)隐式捕获:使用哪些变量就捕获哪些变量
隐式以值得方式捕获了a
int main()
{
int a = 30;
auto f = [=] { return a; };
a = 0;
auto j = f();
cout << j << endl;//j为30
return 0;
}
隐式以引用得方式捕获了a
int main()
{
int a = 30;
auto f = [&] { return a; };
a = 0;
auto j = f();
cout << j << endl;//j为0
return 0;
}
参数列表
与普通函数得参数类似,但是lambda不能有默认参数。
int main()
{
auto f = [](int p1,int p2) { return p1+p2; };
auto j = f(1,2);
cout << j << endl;
return 0;
}
返回类型
当我们需要为lambda指定返回类型时,必须使用尾置返回类型
int main()
{
int a = 30;
auto f = [](int i)->int{
if (i < 0)
return -1;
else
return 1;
};
a = 0;
auto j = f(-1);
cout << j << endl;
return 0;
}
2、function
function定义在functional头文件中,它是一个模板,指定了可调用对象的类型。
std::function<int(int,int)>
声明了一个function类型,它表示接受两个int、返回一个int的可调用对象。
//普通函数
int add(int i, int j)
{
return i + j;
}
//lambda表达式
auto mod = [](int i, int j) {return i % j; };
//函数对象类
struct divide
{
int operator()(int denominator, int divisor)
{
return denominator / divisor;
}
};
std::function<int(int, int)> f1 = add;
std::function<int(int, int)> f2 = mod;
std::function<int(int, int)> f3 = divide();
std::function<int(int, int)> f4 = [](int i, int j) {return i % j; };
3、bind
据我理解,bind和lambda差不多,只不过它可以和函数结合起来使用,向函数中传递函数外面的参数,而lambda则可以直接捕获外面的变量。可以将bind函数看作一个通用的函数适配器,它接收一个可调用对象,生成一个新的可调用对象来“适应“原对象的参数列表。
auto newCallable = bind(callable, arg_list);
newCallable是一个新的可调用对象
callable是bind接收的可调用对象
arg_list比较复杂,它表示newCallable的第几个参数和callable中的参数相对应,注意,它的个数必须和callable参数个数一样
int add(int i, int j,int m)
{
return i + j+m;
}
int main()
{
auto f1 = std::bind(add,std::placeholders::_2, std::placeholders::_3,11);
cout << f1(1,2,3,4,"sss") << endl;
return 0;
}
上面f1中,
std::placeholders::_2表示f1中的第二个参数和add中第一个参数对应
std::placeholders::_3表示f1中的第三个参数和add中第二个参数对应
11表示add中的第三个参数