C++之STL的algorithm(8)之适配器(bind等)整理
注:整理一些突然学到的C++知识,随时mark一下
例如:忘记的关键字用法,新关键字,新数据结构
C++ 的适配器整理
- C++之STL的algorithm(8)之适配器(bind等)整理
- 一、 集合相关操作算法
- 1、函数对象适配器
- 1.1 利用bind2nd进行绑定
- 1.2 继承public binary_function<参数1 类型,参数2类型,返回值类型>
- 2. 取反适配器
- 2.1 一元取反
- 2.2 二元取反
- 3. 函数指针适配器
- 3.1 ptr_fun将普通函数指针适配成函数对象
- 4. 成员函数适配器
- 4.1 如果存放的是对象实体 mem_fun_ref
- 4.2 如果存放的是对象指针 mem_fun
- 总结
提示:本文为 C++ 适配器的写法和举例
一、 集合相关操作算法
C++中的适配器是一种设计模式,它允许将某个类的接口转换为客户端所期望的另一种接口,从而使得原本不兼容的接口能够协同工作。在C++标准库中,适配器模式被广泛应用在函数对象和迭代器等组件上。
下面,每一种适配器模式给出简要的描述和代码示例。
1、函数对象适配器
函数对象适配器用于将一个二元函数对象(即带有两个参数的函数对象)适配为只接受一个参数的函数对象。
1.1 利用bind2nd进行绑定
bind2nd用于将一个二元函数对象的第二个参数绑定为某个固定值,生成一个新的一元函数对象。
cpp复制
#include <functional>
#include <iostream>
int main() {
std::plus<int> plusObj;
std::binder2nd<std::plus<int>> binder(plusObj, std::placeholders::_2);
binder(5); // 这其实是不合法的,因为bind2nd返回的是一个一元函数对象,需要提供一个参数
// 正确的使用方式是与其他函数适配器结合使用,例如与std::bind
auto bound_func = std::bind(binder, std::placeholders::_1); std::cout << bound_func(3) << std::endl;
// 输出8,因为相当于plusObj(3, 5)
return 0;}
1.2 继承public binary_function<参数1 类型,参数2类型,返回值类型>
binary_function是一个模板基类,提供了first_argument_type、second_argument_type和result_type三个嵌套类型,用于描述二元函数对象的参数类型和返回值类型。
#include <functional>
struct MyBinaryFunction : public std::binary_function<int, int, int> { int operator()(int a, int b) const { return a + b; }};
int main() { MyBinaryFunction myFunc;
std::cout << myFunc(3, 4) << std::endl; // 输出7
return 0;}
2. 取反适配器
取反适配器用于将一个函数对象的返回值取反。
2.1 一元取反
not1not1用于生成一个返回值为原函数对象返回值逻辑非的一元函数对象。
#include <functional>
#include <iostream>
bool is_positive(int x) { return x > 0;}
int main() { std::function<bool(int)> func = is_positive;
std::not1<std::function<bool(int)>> notFunc(func);
std::cout << notFunc(-3) << std::endl; // 输出1(true),因为-3不是正数
return 0;
}
2.2 二元取反
not2not2用于生成一个返回值为原二元函数对象返回值逻辑非的一元函数对象。
#include <functional>#include <iostream>bool compare(int a, int b) { return a < b;}int main() { std::function<bool(int, int)> func = compare; std::not2<std::function<bool(int, int)>> notFunc(func);
std::cout << notFunc(5, 3) << std::endl; // 输出1(true),因为5不小于3
return 0;}
3. 函数指针适配器
函数指针适配器用于将普通函数指针适配为函数对象。
3.1 ptr_fun将普通函数指针适配成函数对象
#include <functional>
#include <iostream>
int add(int a, int b) { return a + b;}
int main() { std::pointer_to_binary_function<int, int, int> funcPtrAdapter(add);
std::cout << funcPtrAdapter(3, 4) << std::endl; // 输出7
return 0;}
4. 成员函数适配器
成员函数适配器用于将类的成员函数适配为函数对象。
4.1 如果存放的是对象实体 mem_fun_ref
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
struct MyClass { int value;
MyClass(int v) : value(v) {} int get_value() const { return value; }};
int main() { std::vector<MyClass> vec{MyClass(3), MyClass(5), MyClass(1)};
std::sort(vec.begin(), vec.end(), std::mem_fun_ref(&MyClass::get_value));
for (const auto& obj : vec) { std::cout << obj.value << ' ';
} std::cout << std::endl; // 输出 1 3 5
return 0;}
4.2 如果存放的是对象指针 mem_fun
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
struct MyClass {
int value; MyClass(int v) : value(v) {} int get_value() const { return value; }};
int main() {
std::vector<MyClass*> vec{new MyClass(3), new MyClass(5), new MyClass(1)};
std::sort(vec.begin(), vec.end(), std::mem_fun(&MyClass::get_value));
for (MyClass* obj : vec) { std::cout << obj->value << ' '; } std::cout << std::endl; // 输出 1 3 5 // 释放内存
for (MyClass* obj : vec) { delete obj; }
return 0;}
请注意,由于std::mem_fun、std::mem_fun_ref、std::ptr_fun、std::bind2nd、std::binder2nd等函数适配器在C++11之后逐渐被认为是不推荐的,并在C++17中被移除,因此在实际编程中,我们更推荐使用std::bind、std::function以及lambda表达式来创建函数对象和适配器。上面的代码示例主要是为了展示这些适配器的使用方式,并不推荐在实际项目中使用。