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++标准委员会库工作组成员发起,其中有些内容有望成 ...
随机推荐
- 教你建立SQL数据库的表分区
1)新建一个数据库 2)添加几个文件组 3)回到“常规”选项卡,添加数据库文件 看到用红色框框起来的地方没?上一步中建立的文件组在这里就用上了.再看后面的路径,我把每一个文件都单独放在不同的磁盘上,而 ...
- 【LeetCode 73】矩阵置零
题目链接 [题解] 如果a[i][j]==0. 就把第i行的第一个数字置为0 然后把第j列的第一个数字置为0 最后再处理下每行第一个为0的行.每列第一个为0的列. (第一行和第一列都得用同一个位置处理 ...
- tom
题目描述 众所周知,Tom 猫对香肠非常感兴趣.有一天,Tom 家里的女主人赏给了Tom 一大堆香肠.这些香肠太多了,以至于Tom 一顿吃不完,于是它把这些香肠串成了一棵树,树的每个节点上都有一个香肠 ...
- LintCode之合并排序数组
题目描述: 我的代码: public class Solution { /* * @param A: sorted integer array A * @param B: sorted integer ...
- 2018-2019 2 20165203 《网络对抗技术》Exp8 Web基础
2018-2019 2 20165203 <网络对抗技术>Exp8 Web基础 实验要求 1.本实践的具体要求有: (1) Web前端HTML(0.5分) 能正常安装.启停Apache.理 ...
- net core配置log4net需要注意的地方
和netframework不一样的是,netcore 没有assembly文件.所以配置的时候需要注意: 1.配置文件可以没有 <configSections> <section n ...
- linux从head.s到start_kernelstart_kernel之---内核重定位后分析
参考: https://biscuitos.github.io/blog/ARM-BOOT/ zImage 重定位之后实践 zImage 重定位之后,ARM 将 pc 指针指向了重定位 zImage ...
- POJ 1860 Currency Exchange (Bellman-Ford)
题目链接:POJ 1860 Description Several currency exchange points are working in our city. Let us suppose t ...
- Java数据访问对象模式
数据访问对象模式或DAO模式用于将低级数据访问API或操作与高级业务服务分离. 以下是数据访问对象模式的参与者. 数据访问对象接口 - 此接口定义要对模型对象执行的标准操作. 数据访问对象具体类 - ...
- IE兼容模式下样式分离错乱,求CSS高手
IE正常模式下访问正常 兼容模式右边图片切换区域样式错乱,求CSS高手! 详细参考网址:www.javams.com