函数对象是指那些可以被传入到其它函数或是从其它函数返回的一类函数。

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库:函数对象的更多相关文章

  1. boost库做什么用呢?

    1.C++标准库不是已经很全面了吗?Boost又不是界面库,它主要解决些什么问题呢?哪类问题?2.Boost的开发人员都是C++标准委员会的吧,为什么没把它列做标准库,有什么不完善的问题吗? 3.Bo ...

  2. boost库在工作(15)绑定器与函数对象之三

    前面已经可以优美地解决两个参数的函数给算法for_each调用了,但是又会遇到这样的一种情况,当需要三个参数或者三个以上的参数给算法for_each调用呢?从STL里的绑定器bind1st,显然是不行 ...

  3. C++ Pirmer : 第十四章 : 重载运算符与类型转换之函数调用运算符与标准库的定义的函数对象

    函数调用运算符 struct test { int operator()(int val) const { return (i > 0 ? i : -i); } }; 所谓的函数调用就是一个类重 ...

  4. 【实习记】2014-08-15文档太少看着源码用cgicc+stl库之模板谓词函数对象

        总结1: 今天找到了昨天scanf的问题答案,scanf与printf一样的神奇而复杂,稍不留神,就会被坑.scanf函数在读入非空白符分割的多个字符串的解决方法是这个:/* 以 | 分割 * ...

  5. 8、泛型程序设计与c++标准模板库5.函数对象

    1.函数对象 函数对象是STL提供的第四类主要组件,它使得STL的应用更加灵活方便,从而增强了算法的通用性.大多数STL算法可以用一个函数对象作为参数.所谓“函数对象”其实就是一个行为类似函数的对象, ...

  6. [C/C++] C/C++延伸学习系列之STL及Boost库概述

    想要彻底搞懂C++是很难的,或许是不太现实的.但是不积硅步,无以至千里,所以抽时间来坚持学习一点,总结一点,多多锻炼几次,相信总有一天我们会变得"了解"C++. 1. C++标准库 ...

  7. C++ | boost库 类的序列化

    是的,这是今年的情人节,一篇还在研究怎么用的文章,文结的时候应该就用成功了. 恩,要有信心 神奇的分割线 不知何时装过boost库的header-only库, 所以ratslam中的boost是可以编 ...

  8. boost库(条件变量)

    1相关理念 (1)类名 条件变量和互斥变量都是boost库中被封装的类. (2)条件变量 条件变量是thread库提供的一种等待线程同步的机制,可实现线程间的通信,它必须与互斥量配合使用,等待另一个线 ...

  9. boost库----enable_shared_from_this类的作用和实现原理

    使用boost库时,经常会看到如下的类 class A:public enable_share_from_this<A> 在什么情况下要使类A继承enable_share_from_thi ...

  10. Boost库

    2014-08-31 Boost库是一个经过千锤百炼.可移植.提供源代码的C++库,作为标准库的后备,是C++标准化进程的发动机之一.Boost库由C++标准委员会库工作组成员发起,其中有些内容有望成 ...

随机推荐

  1. poj 3258:River Hopscotch(二分)

    题目链接 L为N+2块石子中最右边石子位置,0最左,M为可移除块数,求移除后相邻石子可达到的最大距离. #include<iostream> #include<cstdio> ...

  2. 前端开发工具-VsCode插件【个人开发常用】

     前端开发工具-VsCode插件[个人开发常用] Atom One Dark Theme-主题 Chinese (Simplified) Language Pack for Visual Studio ...

  3. 【bzoj1185】[HNOI2007]最小矩形覆盖 (旋转卡壳)

    给你一些点,让你用最小的矩形覆盖这些点 首先有一个结论,矩形的一条边一定在凸包上!!! 枚举凸包上的边 用旋转卡壳在凸包上找矩形另外三点... 注意精度问题 #include<cstdio> ...

  4. SSM - 全局跨域处理

    这几天在开发中编写项目时需要前后端分离,刚好涉及到跨域这个问题,很早之前做项目时也用过,也是在网上找的列子,来源已经无处可寻了,若侵必删! 跨域问题一般出现两者服务器不同或者不同的端口上访问资源时会存 ...

  5. python中split()函数的用法

    函数:split() Python中有split()和os.path.split()两个函数,具体作用如下:split():拆分字符串.通过指定分隔符对字符串进行切片,并返回分割后的字符串列表(lis ...

  6. 判断PC或者是APP

    function isPC() { if (/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) { return fa ...

  7. docker镜像加速遇见的一个问题

    今天运行docker发现了一个问题,运行docker images会报 Cannot connect to the Docker daemon at unix:///var/run/docker.so ...

  8. 102.kaldi 斯坦福语音识别工具的编译

    接着上一节,在编译完了openFST有限状态机之后,便开始了最重要部分,语音识别插件的编译过程 首先看目录是如下所示的 1.首先添加openBLAS的支持,这是一个矩阵运算库,个人觉得这个矩阵运算库 ...

  9. l1和l2正则化

    https://blog.csdn.net/tianguiyuyu/article/details/80438630 以上是莫烦对L1和L2的理解 l2正则:权重的平方和,也就是一个圆 l1正则:权重 ...

  10. 使用matplotlib画出log的图像

    以下内容是学习笔记,若有侵权,立即删除! import math import matplotlib.pyplot as plt import numpy as np if __name__ == ' ...