目录
前言
有三种方法可以给STL算法传递函数信息,函数指针、函数符、lambda表达式。比较如下。
函数指针
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
bool f3(int x)
{
if (x % 3 == 0)
{
std::cout << "x->" << x << std::endl;
return true;
}
return false;
}
// STL中通过函数指针传递信息
void test()
{
vector<int> number(20);
generate(number.begin(), number.end(), std::rand);
std::cout << "num is " << count_if(number.begin(), number.end(), f3);
}
int main()
{
test();
return 0;
}
函数符
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
class f_mod
{
private:
int dv;
public:
f_mod(int d = 1) : dv(d) {}
/*
重载函数调用运算符,使得类的对象可以像函数一样被调用。
适用场景
1、仿函数(Functor): 重载 operator() 的类常被称为仿函数(functor),它们在需要类似函数的行为但又需要更多状态时非常有用。
例如,STL 中的 std::less、std::greater 都是仿函数。
2、函数对象作为回调: 仿函数可以传递给需要函数指针的接口,比如排序、自定义算法等。
3、状态保存: 与普通函数不同,类的对象可以保存状态,适用于需要在多次调用中维护状态的场景。
*/
bool operator()(int x)
{
if (x % dv == 0)
{
std::cout << "x->" << x << std::endl;
return true;
}
return false;
}
};
// STL中通过函数符传递信息
void test()
{
vector<int> number(20);
generate(number.begin(), number.end(), std::rand);
std::cout << "num is " << count_if(number.begin(), number.end(), f_mod(3));
}
int main()
{
test();
return 0;
}
Lambda 表达式
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
// STL中通过lambda传递信息
void test()
{
vector<int> number(20);
generate(number.begin(), number.end(), std::rand);
std::cout << "num is " << count_if(number.begin(), number.end(), [](int x) {return x % 3 == 0;});
}
int main()
{
test();
return 0;
}
Lambda 表达式语法
表达式基本语法
[capture](parameters) -> return_type { // 函数体}
[capture]:捕获列表,指定哪些外部变量可以在 Lambda 中使用。
(parameters):参数列表,类似于普通函数的参数。
-> return_type:返回类型(可选,通常可以省略,编译器会自动推导)。
{}:函数体,包含 Lambda 的具体逻辑。
捕获列表的用法
[]:不捕获任何变量。
[x]:按值捕获变量 x。
[&x]:按引用捕获变量 x。
[=]:按值捕获所有外部变量。
[&]:按引用捕获所有外部变量。
[=, &x]:按值捕获所有变量,但对 x 按引用捕获。
[&, x]:按引用捕获所有变量,但对 x 按值捕获。
为何使用lambda
1、距离
让函数的定义在使用的附近,修改方便。
2、简洁
void test()
{
vector<int> number(20);
generate(number.begin(), number.end(), std::rand);
auto mod3 = [](int x) {return x % 3 == 0;};
std::cout << "num is " << count_if(number.begin(), number.end(), mod3);
bool test = mod3(4);
}
int main()
{
test();
return 0;
}
3、效率
函数指针会阻止内联,函数符和lambda不阻止内联。
4、功能
lambda能访问作用域内的任何变量。