住房建设局子网站,海南网站建设服务,百度收录入口在哪里,网站建设与管理 十四五国规教材std::function#xff1a; 一个通用的函数封装器#xff0c;它允许你存储和调用任何可以被调用的东西#xff0c;例如函数、函数指针、函数对象、Lambda 表达式等。
std::bind#xff1a; 用于创建函数对象。一个可调用对象的绑定版本#xff0c;可以提前绑定某些参数 一个通用的函数封装器它允许你存储和调用任何可以被调用的东西例如函数、函数指针、函数对象、Lambda 表达式等。
std::bind 用于创建函数对象。一个可调用对象的绑定版本可以提前绑定某些参数稍后调用时只需提供剩余的参数。 在某些情况下你可以将它们结合使用例如如果你想创建一个可调用对象该对象包含绑定的参数然后将其存储在 std::function 中。这在某些情况下可以提高代码的可读性和灵活性。
示例
#include iostream
#include functionalint add(int a, int b) {return a b;
}int main() {// 创建一个绑定了参数的可调用对象,绑定参数为2// 占位符_1表示稍后调用时传入的第1个参数放在_1这个位置std::functionint(int) func std::bind(add, 2, std::placeholders::_1);// 调用 std::functionint result func(3); // 这里相当于调用 add(2, 3)std::cout Result: result std::endl;return 0;
}将std::function与std::bind一起使用可以提供一些好处尤其在以下情况下 延迟参数绑定你可以使用std::bind在创建std::function对象时部分绑定参数然后稍后再提供其余的参数。这使得你可以在调用可调用对象时动态地确定一些参数值。 增强可读性std::bind允许你清晰地指定参数的绑定方式这可以提高代码的可读性特别是当你处理复杂的函数签名时。 灵活性结合使用std::function和std::bind可以让你更容易地操作和传递可调用对象。这对于实现通用接口或处理回调函数时特别有用。 减少代码冗余如果你需要多次调用具有相同部分绑定的可调用对象结合使用std::function和std::bind可以减少重复的绑定代码。
在不需要提前绑定参数的情况下可以不使用std::bind()。在C11引入Lambda表达式后使用更加灵活和方便。以下是一个示例演示如何使用 std::function 存储一个普通函数或Lambda表达式
Copy code
#include iostream
#include functional// 普通函数
int add(int a, int b) {return a b;
}int main() {// 使用 std::function 存储普通函数std::functionint(int, int) func1 add;// 使用 Lambda 表达式std::functionint(int, int) func2 [](int a, int b) {return a b;};int result1 func1(2, 3); // 调用 add 函数int result2 func2(4, 5); // 调用 Lambda 表达式std::cout Result 1: result1 std::endl;std::cout Result 2: result2 std::endl;return 0;
} 考虑这种情况可调用对象是类的普通成员函数
成员函数是跟具体的对象绑定的它可以操作该对象中的其他成员变量或者调用其他成员函数。成员函数可以做到分辨哪个对象在调用我是因为有隐藏this指针指向当前调用该函数的对象。比如obj.funcAdd(1,2)效果实际上是Obj::funcAdd(obj, 1, 2);。因此如果可调用对象是普通成员函数我们要绑定一个参数即指向调用对象的指针。
因此比较推荐std::function与std::bind()配合使用或者用lambda表达式 当在一个成员函数中创建函数指针指向另一个普通成员函数时绑定参数为this #include iostream
#include functionalclass MyClass {
public:void func1(int value) {std::cout func1: value std::endl;}void func2(int value) {std::cout func2: value std::endl;}void doSome() {// 使用 std::bind 创建 std::function 对象将其绑定到 func2std::functionvoid(MyClass*, int) functionPtr std::bind(MyClass::func2, this, std::placeholders::_2);// 调用函数指针传入对象实例指针和参数functionPtr(42);}
};int main() {MyClass obj;obj.doSome();return 0;
}当然也可以手动传入this 比如std::bind(MyClass::func2, std::placeholders::_1, std::placeholders::_2); 调用functionPtr(this, 42); 利用lambda表达式作为可调用对象 #include iostream
#include functionalclass MyClass {
public:void func1(int value) {std::cout func1: value std::endl;}void func2(int value) {std::cout func2: value std::endl;}void doSome() {// 使用 Lambda 表达式捕获 this 指针std::functionvoid(int) functionPtr [this](int value) {MemberFunction2(value);};// 调用函数指针不需要传递 this 指针functionPtr(42);}
};int main() {MyClass obj;obj.doSome();return 0;
}还有一种简单的情况如果是在想存储某个对象的某个成员函数的指针则需要传入该对象的地址 #include iostream
#include functionalclass MyClass {
public:void func(int value) {std::cout func: value std::endl;}
};int main() {MyClass obj;// 创建 std::function 对象提前绑定obj如果不绑定则需要手动传入std::functionvoid(int) funcPtr std::bind(MyClass::func, obj, std::placeholders::_1);funcPtr(42);return 0;
}