std::bind(二)
bind - boost 头文件: boost/bind.hpp bind 是一组重载的函数模板.
用来向一个函数(或函数对象)绑定某些参数.
bind的返回值是一个函数对象. 它的源文件太长了. 看不下去. 这里只记下它的用法: 9.1 对于普通函数 假如有函数 fun() 如下:
void fun(int x, int y) {
cout << x << ", " << y << endl;
}
现在我们看看怎么用bind 向其绑定参数.
对于像 fun 这样的普通函数. 若fun 有n个参数. 则 bind 需要 n+ 个参数: 原始函数的地址 以及 n个要绑定的参数. 第1种用法:
向原始函数 fun 绑定所有的参数
boost::bind(&fun, , ) // bind的实参表依次为: 要绑定的函数的地址, 绑定到fun的第一个参数值, 第二个参数值...
// fun有多少个参数, 这里就要提供多少个.
表示将 和 作为参数绑定到 fun 函数.
因为绑定了所有的参数. 现在我们调用bind所返回的函数对象:
boost::bind(&fun, , )( ); //无参数.
就会输出 , 第2种用法:
向原始函数 fun 绑定一部分参数
boost::bind(&fun, , _1) // bind的实参表依次还是: 要绑定的函数的地址, 要绑定到fun的第一个参数值, 然后注意
// 因为我们不打算向fun绑定第2个参数(即我们希望在调用返回的Functor时再指定这个参数的值)
// 所以这里使用 _1 来占位. 这里的 _1 代表该新函数对象被调用时. 实参表的第1个参数.
// 同理下边还会用到 _2 _3 这样的占位符.
这里只为fun绑定了第一个参数3. 所以在调用bind返回的函数对象时. 需要:
boost::bind(&fun, , _1)(); //这个4 会代替 _1 占位符.
输出 ,
同理 boost::bind(&fun, _1, )();
输出 , 第3种用法:
不向 fun 绑定任何参数
boost::bind(&fun, _1, _2) // _1 _2 都是占位符. 上边已经说过了.
所以它就是 将新函数对象在调用时的实参表的第1个参数和第2个参数 绑定到fun函数.
boost::bind(&fun, _1, _2)(, ); // 3将代替_1占位符, 4将代替_2占位符.
输出 ,
同理 boost::bind(&fun, _2, _1)(, ); // 3将代替_1占位符, 4将代替_2占位符.
会输出 ,
同理 boost::bind(&fun, _1, _1)(); // 3将代替_1占位符
会输出 , 对于普通函数就这些. 对于函数对象. 如:
struct Func {
void operator()(int x) {
cout << x << endl;
}
} f;
绑定的时候可能要指出返回值的类型:
boost::bind<void>(f, )(); //指出返回值的类型 void 9.2 对于非静态成员函数 假如有:
struct A {
void func(int x, int y) {
cout << x << "," << y << endl;
}
}; A a;
A* pa = new A; //指针
boost::shared_ptr<A> ptr_a(pa); //智能指针. 现在要向像 A::func 这样的非静态成员函数绑定.
若A::func有n个参数, 则 bind 要有 n+ 个参数: 指向成员函数fun的指针, 绑定到this的对象, n个参数.
如:
boost::bind(&A::func, a, , )(); //输出 3, 4
boost::bind(&A::func, pa, , )(); //输出 3, 4
boost::bind(&A::func, ptr_a, , )();//输出 3, 4
同样可以用 _1 这样的占位符. 如:
boost::bind(&A::func, _1, , )(ptr_a);//输出 3, 4 可以看出. 不论传递给bind 的第2个参数是 对象. 对象指针. 还是智能指针. bind函数都能够正常工作. 9.3 bind嵌套 有个类如下. 记录人的信息:
class Personal_info {
string name_;
int age_;
public:
int get_age();
string name();
}; vector<Personal_info> vec;
...
现在要对 vec 排序. 可以用 bind 函数做一个比较谓词
std::sort(
vec.begin(),
vec.end(),
boost::bind(
std::less<int>(),
boost::bind(&personal_info::age,_1), //_1 占位符是 sort 中调用比较函数时的第一个参数.
boost::bind(&personal_info::age,_2))); //_2 占位符是 sort 中调用比较函数时的第二个参数. 9.4 函数组合 假如有:
vector<int> ints;
...
想用 std::count_if() 来求ints中有多少是 > 且 <= 的. 这在常规代码中通常就要写一个函数来实现这个谓词:
if (i> && i<=) ...
现在用bind则可以:
std::count_if(
ints.begin(), ints.end(),
boost::bind(
std::logical_and<bool>(),
boost::bind(std::greater<int>(),_1,),
boost::bind(std::less_equal<int>(),_1,))); 9.5 绑定到成员变量 有:
map<int, string> my_map;
my_map[]="Boost";my_map[]="Bind";
现在要输出所有元素的 second 成员. 也就是输出这些字符串. 其中的打印函数如下:
void print_string(const string& s) {
std::cout << s << '/n';
}
则可以:
for_each(
my_map.begin(),
my_map.end(),
boost::bind(
&print_string,
boost::bind(&std::map<int,std::string>::value_type::second,_1)
)
); 汗... 看不懂bind的源码. 也不知是如何实现这些功能的. 只能等<<boost源码剖析>>出来了. 注意:
(以下补于08年6月3日) boost::bind() 返回的函数对象会保存要绑定的实参. 而且总是拷贝一份以值的方式保存..
这主要是考虑到被绑定的实参的生命期.
但这并不总是我们期望的. 例如有时我们希望它保存指针或引用: 有函数:
void f(int & x) { ++x; }
然后:
int n = ;
bind(&f, n)(); //我们希望 n==1 . 但实际上没有这样... 要避免这种对象复制. 而要bind得到的函数对象保存实参的引用语义. 可以:
使用 boost::ref() 或 boost::cref() 如
bind(&f, ref(n))(); //OK, 执行后 n==1 如果是绑定一个对象到它的成员函数上. 如:
A a;
bind(&A::fun, a); //则保存的是 a对象的拷贝.
要避免这种拷贝. 除了上面提到的 ref() 外, 也可以:
bind(&A::fun, &a); //用指针. 反正用对象和用指针都可以. 而用指针可以避免对象拷贝的问题. 注意: (以下补于6月10日)
bind () 的第一个参数——被绑定函数——是不被求值的. 如下例: typedef void (*pf)(int);
std::vector<pf> v; //v中有一些函数指针.
std::for_each(v.begin(), v.end(), bind(_1, )); //想实现 _1(5); 这样的调用. 但这样不行! 正确的做法是借助 boost::apply 模板(来自boost/bind/apply.hpp).
apply也是一个函数对象. 它的作用如下:
apply<void> a; //模板参数为函数对象的返回值类型.
a(x); //相当于调用 x();
a(x, y); //相当于调用 x(y);
a(x, y, z); //相当于调用 x(y, z);
所以错误的bind应该写为:
std::for_each(v.begin(), v.end(), bind(apply<void>(), _1, ));
std::bind(二)的更多相关文章
- C++11新特性之二——std::bind  std::function 高级用法
		/* * File: main.cpp * Author: Vicky.H * Email: eclipser@163.com */ #include <iostream> #includ ... 
- C++11 std::function、std::bind和lambda表达式
		参考博客: C++可调用对象详解-https://www.cnblogs.com/Philip-Tell-Truth/p/5814213.html 一.关于std::function与std::bin ... 
- 第19课 lambda vs std::bind
		一. std::bind (一)std::bind实现的关键技术 [编程实验]探索bind原理,实现自己的bind函数 #include <iostream> #include <t ... 
- c++11 符号修饰与函数签名、函数指针、匿名函数、仿函数、std::function与std::bind
		一.符号修饰与函数签名 1.符号修饰 编译器将c++源代码编译成目标文件时,用函数签名的信息对函数名进行改编,形成修饰名.GCC的C++符号修饰方法如下: 1)所有符号都以_z开头 2)名字空间的名字 ... 
- C++11之std::function和std::bind
		std::function是可调用对象的包装器,它最重要的功能是实现延时调用: #include "stdafx.h" #include<iostream>// std ... 
- std::bind和std::function
		std::bind 用于绑定一个函数,返回另外一种调用方式的函数对象 ,可以改变参数顺序 和个数,特别是在多线程的程序中,经常用它将函数进行包装,然后打包发送给工作线程,让工作线程去执行我们的任务. ... 
- std::function,std::bind
		std::function 和 std::bind 标准库函数bind()和function()定义于头文件中(该头文件还包括许多其他函数对象),用于处理函数及函数参数.bind()接受一个函数(或者 ... 
- std::function,std::bind复习
		#include <iostream> #include <functional>//std::bind返回函数对象 void fun1(int a, int b) { std ... 
- C++11 std::bind std::function 高级使用方法
		从最基础的了解,std::bind和std::function /* * File: main.cpp * Author: Vicky.H * Email: eclipser@163.com */ # ... 
随机推荐
- VSFTPD配置TLS/SSL
			今天在OSX上配置Coda2 + Xampp的时候,发现FTP老是不连接到服务器上面,导致每次更改了文件都需要使用scp命令上传到服务器.如果一个文件还好,文件和文件夹一多就得使用rp参数全部提交,再 ... 
- win server 2008配置ftp无法登陆问题的解决办法
			解决办法放在最前面,方便急需答案的同学: 创建了ftp使用的windows账户后,一定要给该账户添加ftp目录的权限,如下图所示,为新账户添加权限后(且设置了“ftp身份验证”),即可正常访问ftp: ... 
- [服务]ftp主动模式和被动模式
			经常忘记这个东西.于是总结下这东西感受下这个协议. FTP连接方式 控制连接:标准端口为21,用于发送FTP命令信息 数据连接:标准端口为20,用于上传.下载数据 数据连接的建立类型: 主动模式:服务 ... 
- Asp.net设计模式笔记之一:理解设计模式
			GOF设计模式著作中的23种设计模式可以分成三组:创建型(Creational),结构型(Structural),行为型(Behavioral).下面来做详细的剖析. 创建型 创建型模式处理对象构造和 ... 
- iOS技巧,宏定义
			aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAnoAAAPCCAYAAADvRHWgAAAAAXNSR0IArs4c6QAAAZ1pVFh0WE1MOm 
- 开发一个简单实用的android紧急求助软件
			之前女朋友一个人住,不怎么放心,想找一个紧急求助的软件,万一有什么突发情况,可以立即知道.用金山手机卫士的手机定位功能可以知道对方的位置状态,但不能主动发送求助信息,在网上了很多的APK,都是鸡肋功能 ... 
- Android空闲教室查询-资料
			这是去年某课程的一个称作“研究型学习”的东西的报告的展示PPT,有点失败的是这个APP的名字起得不太好……PPT上的功能都实现了,其他功能都没有.一年了,程序都忘差不多了,也暂时没有时间分享.就先把P ... 
- Maven(二)核心知识点
			Maven有一些核心的知识点需要了解,比如坐标.仓库.插件.生命周期等概念,这里将依次解释. 坐标 Maven以构件来组成基本的控制单元,而定义这个构件的标示,Maven给定义为“坐标”.坐标是Mav ... 
- Android响应式界面开发要点
			现在很多项目需要到达同一个Apk既可以在Phone上跑也尅在tablet上跑,即界面要适应不同尺寸和类型的需要而自动调整.这个即为响应式设计.在web开发商响应式设计已经是个常谈的内容了,而对于and ... 
- 网页音乐突破金币(RMB)下载限制
			我平时有时间会跳跳舞 跳舞肯定要有音乐呀 于是在网上找音乐 好不容易找到了一个网站,里面有很多很全的音乐 正准备下载呢,尼玛居然要金币! 在这里解释一下,金币你可以通过回复帖子或者发帖子得到,但是数量 ... 
