boost bind 用法
来源:互联网 发布:关键词搜索软件 编辑:程序博客网 时间:2024/06/15 14:11
boost::bind()用来将一个函数或函数对象绑定某些参数,返回值是一个函数对象。
它提供一个任意的函数对象(仿函数)、函数、函数指针、成员函数指针。
上代码:
#include <boost/bind.hpp> #include <iostream> #include <vector> #include <algorithm> void add(int i, int j) { std::cout << i + j << std::endl; } int main() { std::vector<int> v; v.push_back(1); v.push_back(3); v.push_back(2); std::for_each(v.begin(), v.end(), boost::bind(add, 10, _1)); }上述代码中bind绑定了一个一元函数对象。
add()
函数要求两个参数,两个参数都必须传递给boost::bind()
。 第一个参数是常数值10,而第二个参数则是一个怪异的_1。
_1 被称为占位符(placeholder),定义于 Boost.Bind。 除了 _1,Boost.Bind 还定义了_2 和_3。 对于 _1,
boost::bind()
返回一个一元函数,即有且只有一个参数。
当这个程序执行时,std::for_each()
对容器 v 中的每一个元素调用该一元函数。 元素的值通过占位符_1 传入到一元函数中。 这个占位符和常数值被进一步传递到add()
函数。 通过使用这种机制,std::for_each()
只看到了由boost::bind()
所定义的一元函数。 而boost::bind()
本身则只是调用了另一个函数,并将常数值或占位符作为参数传入给它。有点罗嗦。
上述代码有点别扭,对每个元素加10,为什么不是两个参数呢?因为std::for_each()
要求一个一元函数作为其第三个参数。
下面看bind的二元函数用法:
#include <boost/bind.hpp>#include <vector>#include <algorithm>#include <iostream>bool compare(int i, int j){ return i > j;}int main(){ std::vector<int> v{1, 3, 2}; std::sort(v.begin(), v.end(), boost::bind(compare, _1, _2)); for (int i : v) std::cout << i << '\n';}
std::sort()
算法以容器 v 的两个元素来调用该函数,并根据返回值来对容器进行排序。如果compare()为true则swap()
,容器将被按降序排列。但是,由于compare()
本身就是一个二元函数,所以使用 boost::bind()
确是多余的。可以直接这么写:std::sort(v.begin(), v.end(), compare);不过用bind可以方便的反向排序:
std::sort(v.begin(), v.end(), boost::bind(compare, _2, _1));只改变占位符的位置。但是这种先2后1的传参方式还是不用为好。
那么问题来了,看下面的代码—— boost::bind是怎么区分类成员函数和全局函数的?
class ClassA {public: void test(int, int){}} void mytest(ClassA* pObj, int, int) {} typedef boost::function<void (int, int)> func;func f1 = boost::bind(ClassA::test, this, _1, _2);func f2 = boost::bind(mytest, pObj, _1, _2);
关于bind的内部原理,
下面的示例程序说明了一切:
#include <stdio.h> template<typename... ARGS>void bind(void (*func)(ARGS...), ARGS... args){ printf("plain function\n"); func(args...); // std::forward<> 从略。} template<typename CLASS, typename... ARGS>void bind(void (CLASS::*func)(ARGS...), CLASS* clz, ARGS... args){ printf("member function\n"); (clz->*func)(args...);} template<typename CLASS, typename... ARGS>void bind(void (CLASS::*func)(ARGS...) const, const CLASS* clz, ARGS... args){ printf("const member function\n"); (clz->*func)(args...);} void foo(int arg){ printf("foo %d\n", arg);} class Bar{ public: void write(double arg) { printf("Bar::write %f\n", arg); } void read(long arg) const { printf("Bar::read %ld\n", arg); }}; void zoo(Bar* x){ printf("zoo %p\n", x);} int main(){ bind(foo, 123); Bar bar; bind(&Bar::write, &bar, 3.14); bind(&Bar::read, &bar, 42L); bind(zoo, &bar);}
这是Partial Template Specialization技术,即模板的"偏特化"或叫"部分特化"。
0 0
- Boost bind 用法
- boost.bind用法
- boost function bind用法
- boost.bind用法
- boost::bind()用法
- boost bind 用法
- Boost.Bind用法详解
- boost bind function用法说明
- 【Boost】boost库中bind的用法
- Boost.Bind用法详解(一)
- Boost.Bind用法详解(二)
- boost库中bind的用法
- boost库bind的一些用法
- Boost.Bind用法详解(一)
- Boost.Bind用法详解(二)
- C++:boost::bind的一些用法
- boost.bind
- boost::bind
- SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)
- Objective-C中不同方式实现锁(二)
- 在基于MFC的对话框里使用glut库函数
- 工作总结 8.9-18
- 通过运算符重载实现复数运算
- boost bind 用法
- iGrimace IG1.44和V3.0.0 版本区别
- 比较全面的JS验证
- [leetcode][string] Longest Palindromic Substring
- CCF 201312-2ISBN号码
- IOS Frame 和 Bounds的区别(自己的理解以便以后使用)
- Android SDK Manager不能显示所有包的解决办法
- 欢迎使用CSDN-markdown编辑器
- OC中数组的四种遍历方式