函数绑定的目的
The purpose of Function Binding
我正在学习 c++ Boost 库的 asio 编程。我遇到过许多使用函数 bind(( 的例子,它以函数指针作为参数。
我一直无法理解 bind(( 函数的使用。这就是为什么我很难理解使用asio的boost库的程序。
我不在这里寻找任何代码。我只想知道 bind(( 函数或其任何等效函数的用法。提前谢谢。
来自 cpp首选项
函数模板绑定为 f 生成转发调用包装器。 调用这个包装器等效于用它的一些东西调用 f 绑定到参数的参数。
检查以下示例,演示绑定
#include <iostream>
#include <functional>
using namespace std;
int my_f(int a, int b)
{
return 2 * a + b;
}
int main()
{
using namespace std::placeholders; // for _1, _2, _3...
// Invert the order of arguments
auto my_f_inv = bind(my_f, _2, _1); // 2 args b and a
// Fix first argument as 10
auto my_f_1_10 = bind(my_f, 10, _1); // 1 arg b
// Fix second argument as 10
auto my_f_2_10 = bind(my_f, _1, 10); // 1 arg a
// Fix both arguments as 10
auto my_f_both_10 = bind(my_f, 10, 10); // no args
cout << my_f(5, 15) << endl; // expect 25
cout << my_f_inv(5, 15) << endl; // expect 35
cout << my_f_1_10(5) << endl; // expect 25
cout << my_f_2_10(5) << endl; // expect 20
cout << my_f_both_10() << endl; // expect 30
return 0;
}
可以使用 bind 来操作现有函数的参数顺序或修复某些参数。这在 stl 容器和算法中特别有用,您可以在其中传递其签名与您的要求匹配的现有库函数。
例如,如果要将容器中的所有双精度转换为 2 的幂,只需执行以下操作:
std::transform(begin(dbl_vec),
end(dbl_vec),
begin(dbl_vec),
std::bind(std::pow, _1, 2));
现场示例在这里
发布到boost::asio
服务的任务必须可以使用零参数调用,以便服务可以存储它们并在拥有备用资源(即空闲线程(后调用它们。假设您希望它调用函数void purr(int kitty)
,为了以可以使用的格式将其提供给服务,您需要将kitty
参数绑定到purr
函数。这将为您提供一个对象,该对象可调用()
您不能向服务提供任何参数。
当然,对于 C++11 和 lambda 函数,现在最好的方法是执行io_service.post([&](){ purr(3); });
并完全避免使用bind
。
它允许您将自己的数据与您希望库调用的函数相关联(或"绑定"(,而无需库知道有关数据的任何信息。
由于您正在查看 Boost.Asio,请查看他们的教程,了解如何将参数绑定到处理程序。他们有一个想要用作处理程序的函数,该函数需要指向自己数据的指针、计时器本身和一个计数器:
void print(const boost::system::error_code& /*e*/,
boost::asio::deadline_timer* t, int* count)
{
// ...
}
计时器的 async_wait
函数导致在计时器过期时调用用户提供的函数;但仅提供这些参数中的第一个。处理程序的格式为
void handler(
const boost::system::error_code& error // Result of operation.
);
因此,我们可以使用bind
将我们的函数(需要三个参数(转换为只需要一个参数的函数,方法是指定要作为其他两个参数传递的值:
t.async_wait(boost::bind(print,
boost::asio::placeholders::error, &t, &count));
bind
的结果是一个函数对象(即重载函数调用运算符 operator()
的类类型的对象(,在本例中采用单个参数。placeholders::error
参数表示第一个参数仍然是新函数类型的参数;调用新函数时,其他两个参数的值为 &t
和 &count
。因此,如果我们自己称呼它:
auto f = boost::bind(print, boost::asio::placeholders::error, &t, &count)
f(some_error);
这将具有与使用这些参数调用原始函数相同的效果:
print(some_error, &t, &count);
现在,当计时器到期时,使用我们提供的参数调用我们的函数,而 Asio 库不需要知道有关它们的任何信息。
- 传递给 lambda C++绑定函数
- 是否可以将绑定函数存储在容器中?
- C++绑定函数到指针
- 我正在尝试制作一个在 std::bind 之前匹配的网络绑定函数
- 用emscripten中的参考参数绑定函数
- C++-模板函数接受绑定函数作为参数并将其传递给另一个函数
- 将绑定函数分配给 std::函数
- C++中的绑定函数结果
- 绑定函数而不提供参数类型
- std::bind 一个绑定函数
- 创建具有提升绑定/函数的菜单处理程序
- C++绑定函数以用作其他函数的参数
- C++ Boost::bind:指向绑定函数的指针只能用于调用该函数
- 如何指定可能接受 boost::绑定函数的 C++ 函数指针
- 指向绑定函数的指针只能用于调用该函数
- boost::spirit绑定函数,提供参数为spirit:qi::_val
- 套接字绑定函数编译错误
- 在绑定函数/使用lambdas测试消息传递代码时遇到麻烦
- 错误:指向绑定函数的指针只能用于调用该函数
- Windows套接字api绑定函数编译问题