boost库:函数对象
函数对象是指那些可以被传入到其它函数或是从其它函数返回的一类函数。
1. boost::bind
bind提供了一个机制,是函数与几乎不限数量的参数一起使用,就可以得到指定签名的函数。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();
v.push_back();
v.push_back(); std::for_each(v.begin(), v.end(), boost::bind(add, , _1)); return ;
}
add()函数要求两个参数,两个参数都必须传递给boost::bind()。第一个参数是10,第二个则是一个占位符,还有其他的占位符_2, _3。
使用这些占位符,boost::bind()可以变为一元、二元或三元的函数。对于_1,boost::bind()变成了一个一元函数,只需要一个参数的函数,而std::for_each()要求一个一元函数作为其第三个参数。程序执行,v中元素的值通过占位符_1传入到医院函数中,并进一步和常数一起传递到add()函数。通过这种机制,std::for_each()只看到了由boost::bind()定义的一元函数,而boost::bind()本身则是调用了另一个函数。
2. boost::ref
由于bind是复制传递给它的参数,如果参数为引用,则需要使用boost::ref(),boost::cref()
#include <boost/bind.hpp>
#include <iostream>
#include <vector>
#include <algorithm> void add(int i, int j, std::ostream& os) {
os << i + j << std::endl;
} int main() {
std::vector<int> v;
v.push_back();
v.push_back();
v.push_back(); std::for_each(v.begin(), v.end(), boost::bind(add, , _1, boost::ref(std::cout)));
}
3. boost::function
用来封装函数指针,
#include <boost/function.hpp>
#include <iostream>
#include <cstdlib>
#include <cstring> int main() {
boost::function<int (const char*)> f = std::atoi;
std::cout << f("") << std::endl; //调用atoi()
f = std::strlen;
std::cout << f("") << std::endl; //调用strlen()
return ;
}
boost::function可以定义一个指针,指向具有特定签名的函数。如上,定义了一个指针f,可以指向某个接受一个类型为const char*的参数且返回一个类型为int的值的函数。定义完成后,匹配此签名的函数均可赋值给这个指针呢。
若f未赋予一个函数而被调用,则会抛出一个boost::bad_function_call异常。若将0赋给一个boost::function类型的函数指针,将会释放所赋的函数。释放之后在调用也会导致boost::bad_function_call异常被抛出。要检查一个函数指针是否被赋予某个函数,可以使用empty()或operator bool()操作符。
#include <boost/function.hpp>
#include <iostream> struct world {
void hello(std::ostream& os) {
os << "Hello, world!" << std::endl;
}
} int main() {
boost::function<void (world*, std::ostrema&)> f = &world::hello;
world w;
f(&w, boost::ref(std::cout));
return ;
}
在调用这样的一个函数时,传入的第一个参数表示了该函数被调用的那个特定对象。因此,在模板定义中的左括号的第一个参数必须是该特定类型的指针,接下来的参数才是表示相应的成员函数的签名。
4. boost::lambda
匿名函数,可以使源代码更为紧凑。
#include <boost/lambda/lambda.hpp>
#include <iostream>
#include <vector>
#include <algorithm> int main() {
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3); std::for_each(v.begin(), v.end(), std::cout << boost::lambda::_1 << "\n");
return 0;
}
通过lambda::_1占位符,容器v的元素可以通过<<传给std::cout以将它们输出到标准输出。有一个例子:
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/if.hpp>
#include <iostream>
#include <vector>
#include <algorithm> int main() {
std::vector<int> v;
v.push_back();
v.push_back();
v.push_bakc(); std::for_each(v.begin(), v.end(), boost::lambda::if_then(boost::lambda::_1 > , std::cout << boost::lambda::_1 << "\n"));
return ;
}
boost库:函数对象的更多相关文章
- boost库做什么用呢?
1.C++标准库不是已经很全面了吗?Boost又不是界面库,它主要解决些什么问题呢?哪类问题?2.Boost的开发人员都是C++标准委员会的吧,为什么没把它列做标准库,有什么不完善的问题吗? 3.Bo ...
- boost库在工作(15)绑定器与函数对象之三
前面已经可以优美地解决两个参数的函数给算法for_each调用了,但是又会遇到这样的一种情况,当需要三个参数或者三个以上的参数给算法for_each调用呢?从STL里的绑定器bind1st,显然是不行 ...
- C++ Pirmer : 第十四章 : 重载运算符与类型转换之函数调用运算符与标准库的定义的函数对象
函数调用运算符 struct test { int operator()(int val) const { return (i > 0 ? i : -i); } }; 所谓的函数调用就是一个类重 ...
- 【实习记】2014-08-15文档太少看着源码用cgicc+stl库之模板谓词函数对象
总结1: 今天找到了昨天scanf的问题答案,scanf与printf一样的神奇而复杂,稍不留神,就会被坑.scanf函数在读入非空白符分割的多个字符串的解决方法是这个:/* 以 | 分割 * ...
- 8、泛型程序设计与c++标准模板库5.函数对象
1.函数对象 函数对象是STL提供的第四类主要组件,它使得STL的应用更加灵活方便,从而增强了算法的通用性.大多数STL算法可以用一个函数对象作为参数.所谓“函数对象”其实就是一个行为类似函数的对象, ...
- [C/C++] C/C++延伸学习系列之STL及Boost库概述
想要彻底搞懂C++是很难的,或许是不太现实的.但是不积硅步,无以至千里,所以抽时间来坚持学习一点,总结一点,多多锻炼几次,相信总有一天我们会变得"了解"C++. 1. C++标准库 ...
- C++ | boost库 类的序列化
是的,这是今年的情人节,一篇还在研究怎么用的文章,文结的时候应该就用成功了. 恩,要有信心 神奇的分割线 不知何时装过boost库的header-only库, 所以ratslam中的boost是可以编 ...
- boost库(条件变量)
1相关理念 (1)类名 条件变量和互斥变量都是boost库中被封装的类. (2)条件变量 条件变量是thread库提供的一种等待线程同步的机制,可实现线程间的通信,它必须与互斥量配合使用,等待另一个线 ...
- boost库----enable_shared_from_this类的作用和实现原理
使用boost库时,经常会看到如下的类 class A:public enable_share_from_this<A> 在什么情况下要使类A继承enable_share_from_thi ...
- Boost库
2014-08-31 Boost库是一个经过千锤百炼.可移植.提供源代码的C++库,作为标准库的后备,是C++标准化进程的发动机之一.Boost库由C++标准委员会库工作组成员发起,其中有些内容有望成 ...
随机推荐
- 5 November in 614
Contest A. ssoj2964 交错的士兵 \(n\) 个数的排列,从左到右依次为 1, 2, -, \(n\).\(n\) 次操作,对于第 \(i\) 次操作,从左到右分成很多段,每段 \( ...
- python中的_ElementUnicodeResult是什么
_ElementUnicodeResult在python中是字符串的一种,因为在python3中,字符串就是指以unicode编码规则存储的数据,而以其他方式如utf-8,ASCII编码方式存储的数据 ...
- ubuntu 配置jre后出现问题Error occurred during initialization of VM
百度了好久,找到了一个可以解决的办法. https://blog.51cto.com/chris2013/1313117 就是在usr/java/jre/lib/rt.pack需要解压成rt.jar ...
- Jmeter处理https请求
首先来看一下HTTPS和HTTP的区别主要如下: 1.https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用. 2.http是超文本传输协议,信息是明文传输,https则是具有安全性的s ...
- vmware导出OVF文件失败
从VMware菜单栏选择导出到 .ovf. 显示导出失败 "Failed to open ..... .vmx". 尝试直接打开虚拟机,系统全部正常. 打开虚拟机所在目录,查找后缀 ...
- 杂项-网络-DNS-IP:8.8.8.8
ylbtech-杂项-网络-DNS-IP:8.8.8.8 8.8.8.8是一个IP地址,是Google提供的免费DNS服务器的IP地址,Google提供的另外一个免费DNS服务器的IP地址是:8.8. ...
- iview+vue 表格中添加图片
开门见山,话不多说,要在表格中添加图片,可以使用td: <table " width="100%"> <tr class="tr-style ...
- zabbix配置-模板
1.配置=>模板=>创建模板=>输入模板名称和群组 2.配置=>模板=>找到刚刚创建的模板=>点击应用集(applications)=>创建应用集=>输 ...
- day106 支付功能与优惠券功能 contentype
https://blog.csdn.net/Ayhan_huang/article/details/78626957 一.ContenType from django.db import models ...
- Cocos2d-x之Map<K, V>
| 版权声明:本文为博主原创文章,未经博主允许不得转载. Map<K, V>是Cocos2d-x 3.0x中推出的字典容器,它也能容纳Ref类型.Map<K,V>是模仿C+ ...