头文件
#include <functional>
作用
适配器是一种特殊的函数对象,它可以将一个谓词或函数对象转换为另一种形式,以适应不同的算法需求。
绑定器(Binder)适配器
概念
绑定器:bind()
//bind函数是C++11引入的。bind1st、bind2nd函数是早期版本的C++标准库中的函数,它是bind函数的一种特殊形式。
//为了区分不同的参数,C++11引入两个占位符(placeholders::_1和placeholders::_2)
他们的作用是在绑定函数对象时,暂时不指定参数的值,而是将参数的位置占位。在实际调用函数对象时,再通过bind函数或其他方式将实际的参数传递给占位符所表示的位置。
下例中1000是第二个参数,v中每次传入的是第一个参数
作用
可以将一个带有多个参数的函数对象或函数指针转换为一个只接受部分参数的函数对象。
例:在遍历容器时,为容器中的每个元素加上100
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
class MyPrint {
public:
void operator()(int v1, int v2) const {
cout << v1 + v2 << endl;
}
};
int main() {
vector<int> v = {10, 20, 30, 40, 50};
MyPrint myPrint;
for_each(v.begin(), v.end(), bind(myPrint, placeholders::_1, 1000));
cout << std::endl;
return 0;
}
取反器(Negator)适配器
概念
not1适配器:接受一个一元谓词作为参数,并返回一个新的谓词对象,该对象对原谓词的结果进行取反操作。
not2适配器:接受一个二元谓词作为参数,并返回一个新的谓词对象,该对象对原谓词的结果进行取反操作。
not1适配器
class MyGreaterThan3
{
public:
bool operator()(int val) const {
return val > 3;
}
};
int main()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
// 找出第一个大于3的数
vector<int>::iterator ret;
ret = find_if(v.begin(), v.end(), MyGreaterThan3());
if (ret != v.end()) {
cout << *ret << endl;
}
// 找出第一个小于3的数
ret = find_if(v.begin(), v.end(), not1(MyGreaterThan3()));
if (ret != v.end()) {
cout << *ret << endl;
}
return 0;
}
not2适配器
class MyGreaterInt
{
public:
bool operator()(int val1, int val2) const {
return val1 > val2;
}
};
int main()
{
vector<int> v;
v.push_back(5);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(1);
for_each(v.begin(), v.end(), [](int val) {
cout << val << " ";
});
cout << endl;
sort(v.begin(), v.end(), MyGreaterInt());
for_each(v.begin(), v.end(), [](int val) {
cout << val << " ";
});
cout << endl;
sort(v.begin(), v.end(), [](int val1, int val2) {
return val1 < val2;
});
for_each(v.begin(), v.end(), [](int val) {
cout << val << " ";
});
cout << endl;
return 0;
}
成员函数(Member Function)适配器
作用
用于将成员函数转换为函数对象,以便在算法中使用。
类型
mem_fun适配器:将成员函数转换为一元函数对象,可以用于接受一个参数的算法。
mem_fun_ref适配器:将成员函数转换为二元函数对象,可以用于接受两个参数的算法。
mem_fun适配器
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
class Person {
public:
Person(const std::string& name) : name(name) {}
void sayHello() const {
std::cout << "Hello, my name is " << name << std::endl;
}
private:
std::string name;
};
int main() {
std::vector<Person> persons;
persons.push_back(Person("Alice"));
persons.push_back(Person("Bob"));
persons.push_back(Person("Charlie"));
std::for_each(persons.begin(), persons.end(), std::mem_fun(&Person::sayHello));
return 0;
}
//输出
Hello, my name is Alice
Hello, my name is Bob
Hello, my name is Charlie
mem_fun_ref 适配器
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
class Rectangle {
public:
Rectangle(int width, int height) : width(width), height(height) {}
int calculateArea() const {
return width * height;
}
private:
int width;
int height;
};
int main() {
std::vector<Rectangle> rectangles;
rectangles.push_back(Rectangle(3, 4));
rectangles.push_back(Rectangle(2, 5));
rectangles.push_back(Rectangle(6, 2));
int totalArea = 0;
std::for_each(rectangles.begin(), rectangles.end(), std::mem_fun_ref(&Rectangle::calculateArea));
std::for_each(rectangles.begin(), rectangles.end(), [&totalArea](const Rectangle& r) {
totalArea += r.calculateArea();
});
std::cout << "Total area: " << totalArea << std::endl;
return 0;
}
//输出
Total area: 40