本文根据boost的教程整理。

主要介绍boost function对象的用法。

boost function

boost function是什么

boost function是一组类和模板组合,用于包装各种函数。从功能上,它类似于函数指针,但是比函数指针的功能更强大。

使用boost function,必须包含头文件

#include <boost/function.hpp>

除了头文件外,不需要额外的库。

注意,boost function有两种形式:一种为推荐形式;另外一种为可移植形式。推荐形式的语法更加简洁;可移植形式的可移植性好,但是语法罗嗦。由于目前的gcc/vc的版本都已经能够使用推荐形式了,因此,可移植形式就不在描述。有兴趣的可以参阅boost相关文档。

boost function 基本用法

例如,有一个函数

float int_div(int x, int y)
{return ((float)x)/y;
}

我们可以这样使用

    boost::function<float (int x, int y)> f;f = int_div;std::cout<< f(5,3) << std::endl;

可以看到,它的用法和函数指针很相似的。

当然,boost::function不止这些,请看下面的函数对象:

struct int_add {float operator()(int x, int y) {return (float)(x + y);}
};

上面的 boost::function<float (int x, int y)> f 声明的f对象,仍旧可以保存int_add:

    f = int_add();std::cout << "f add : "<< f(10,20) << std::endl;

另外,boost::function还可以用来判断函数是否为空

    if(f)std::cout  << " f is ok!"<< std::endl;

要清空f,可以使用

    f = 0;if(!f)std::cout << "f is cleard!" << std::endl;

针对成员函数

成员函数,也可以被绑定,如有类
struct X {int foo(int x) {std::cout << "X " << this << " foo x="<<x << std::endl;return x + 100;};
};

可以这样使用

    boost::function<int (X*, int)> mf;mf = &X::foo;X x;mf(&x, 5);

和bind同时使用

在需要包装参数的场合,我们可以配合boost::bind一起使用。
首先,加入boost::bind的头文件
#include <boost/bind.hpp>

这样使用

    boost::function<int (int)> mbf;mbf = bind(&X::foo, &x, _1);mbf(10);

bind将x的指针保存在function对象中。

function factory

function factory是一个封装类工厂的模板。它有两种,一种是value_factory,一种是factory。
boost::factory<T*>()(arg1,arg2,arg3)
// same as new T(arg1,arg2,arg3)boost::value_factory<T>()(arg1,arg2,arg3)
// same as T(arg1,arg2,arg3)

使用function factory的原因

我们考虑这样的场景:使用 抽象工厂模式,有一个接口,有若干个实现,通常的做法是这样的:
//声明接口
class Interface
{
public:virtual void print(int a) = 0; //接口函数
};
//声明抽象工厂
class Interface_Factory {
public:virtual Interface * create() = 0;
};

然后,我们有若干个实现

class ImplA : public Interface
{
public:virtual void print(int a) {std::cout << "== A ==  a=" << a << std::endl;}
};
//提供ImplA的类工厂
class ImplA_Factory : public Interface_Factory
{
public:Interface * create() { return new ImplA(); }static ImplA_Factory _implAFactory;
};
ImplA_Factory ImplA_Factory::_implAFactory;//同理,ImplB的实现class ImplB : public Interface
{
public:virtual void print(int a) {std::cout << "== B ==  a=" << a << std::endl;}
};
//提供ImplB的类工厂
class ImplB_Factory : public Interface_Factory
{
public:Interface * create() { return new ImplB(); }static ImplB_Factory _implBFactory;
};
ImplB_Factory ImplB_Factory::_implBFactory;

如果你要使用它,就需要这些写

std::map<std::string, Interface_Factory*> factories;int main()
{factories["A"] = &ImplA_Factory::_implAFactory;factories["B"] = &ImplB_Factory::_implBFactory;
.....
}

如果仔细观察下,就会发现,实际上,ImplA_Factory和ImplB_Factory的内容几乎都一样。但是却写了不少重复性的代码。factory就是解决该问题的。

factory的解决之道

使用boost::factory,是完全不需要定义Interface_Factory接口和对应的实现的,我们定义一个boost::function对象,替代Interface_Factory
typedef boost::function< I *() > I_factory; //替代Interface_Factory的定义
用boost::factory替代ImplA_Factory和ImplB_Factory:
std::map<std::string, I_factory> factories;
....factories["A"] = boost::factory<ImplA*> ();  //等价于 &ImplA_Factory::_ImplAFactory;factories["B"] = boost::factory<ImplB*> (); //等价于 &ImplB_Factory::_ImplBFactory;

在使用的时候,与普通方法丝毫不差,如

void run_interface(const char* name)
{I_factory factory = factories[name];if(!factory){   std::cout<<"factory " << name << " is not exist" << std::endl;return;}   I *i = factory();i->print(100);delete i;
}

通过判断factory的函数是否为空,就可以知道对应的类实现是否存在。我们可以这样简单的使用

    run_interface("A");run_interface("B");run_interface("C");

由于"C"对象不存在,因此,将打印 "factory C is not exist"的信息。

OverloadedFunction

考虑下面的代码

const std::string& identity_s(const std::string& x) // Function (as pointer).{ return x; }int identity_i_impl(int x) { return x; }
int (&identity_i)(int) = identity_i_impl; // Function reference.double identity_d_impl(double x) { return x; }
boost::function<double (double)> identity_d = identity_d_impl; // Functor.

在调用他们的时候,必须使用各自的函数名:identity_i, indentity_s, indentity_d; 例如

BOOST_TEST(identity_s("abc") == "abc");
BOOST_TEST(identity_i(123) == 123);
BOOST_TEST(identity_d(1.23) == 1.23);

但是,使用OverlaodedFunction,就可以使用统一的名字identity来调用了:

boost::overloaded_function<const std::string& (const std::string&), int (int), double (double)
> identity(identity_s, identity_i, identity_d);// All calls via single `identity` function.
BOOST_TEST(identity("abc") == "abc");
BOOST_TEST(identity(123) == 123);
BOOST_TEST(identity(1.23) == 1.23);

转载于:https://www.cnblogs.com/snake-hand/p/3141026.html

boost function对象相关推荐

  1. 使用 Boost.Lambda 库创建并存储在 Boost.Function 对象中的函子中使用 Boost.Units 的数量、单位和绝对类型

    使用 Boost.Lambda 库创建并存储在 Boost.Function 对象中的函子中使用 Boost.Units 的数量.单位和绝对类型 实现功能 C++实现代码 实现功能 使用 Boost. ...

  2. boost::function的用法(二)

    boost function是一组类和模板组合,用于包装各种函数.从功能上,它类似于函数指针,但是比函数指针的功能更强大. 使用boost function,必须包含头文件 [cpp] view pl ...

  3. [转] boost::function用法详解

    http://blog.csdn.net/benny5609/article/details/2324474 要开始使用 Boost.Function, 就要包含头文件 "boost/fun ...

  4. boost源码剖析之:泛型函数指针类boost::function(rev#3)

    boost源码剖析之:泛型函数指针类boost::function(rev#3) 刘未鹏 C++的罗浮宫(http://blog.csdn.net/pongba)   Note: 并非新作,03年曾放 ...

  5. boost::function/bind

    boost::function/bind boost::function 头文件:<boost/function.hpp> boost::function是一个函数模板,可以代替具有相同返 ...

  6. 【Boost】以boost::function和boost:bind取代虚函数

    这是一篇比较情绪化的blog,中心思想是"继承就像一条贼船,上去就下不来了",而借助boost::function和boost::bind,大多数情况下,你都不用上贼船. boos ...

  7. boost::function和boost:bind取代虚函数

    这是一篇比较情绪化的blog,中心思想是"继承就像一条贼船,上去就下不来了",而借助boost::function和boost::bind,大多数情况下,你都不用上贼船. boos ...

  8. boost::function的用法(一)

    boost::function的用法 本片文章主要介绍boost::function的用法. boost::function 就是一个函数的包装器(function wrapper),用来定义函数对象 ...

  9. boost::function用法详解

    要开始使用 Boost.Function, 就要包含头文件 "boost/function.hpp", 或者某个带数字的版本,从 "boost/function/func ...

最新文章

  1. C++ 笔记(05)— 变量(变量定义、声明、初始化、extern关键字、变量之间转换)
  2. SAP 固定资产减值准备配置及期初导入
  3. ITK:将真实和虚构图像转换为复杂图像
  4. Linux下arp用法
  5. 协同过滤——基于邻域的算法
  6. 神经网络 tensorflow :损失函数
  7. 为什么计算机有信息记忆功能,为什么计算机有记忆能力
  8. java中两任务并行运行_Java并行编程中的“可调用”与“可运行”任务
  9. 卷积神经网络——各种网络的简洁介绍和实现
  10. 大公司里学做人,小公司里学做事。
  11. 第11章 享元模式(Flyweight Pattern)
  12. iOS 内存泄漏的常见场景
  13. c语言erf函数,erf_数值 | Numerics_C_参考手册_非常教程
  14. WindRiver编译小结
  15. 数字图像处理的发展历史、应用领域、主要来源
  16. 每日简报 5月2日简报新鲜事 每天一分钟 了解新鲜事
  17. BootCDN和npm
  18. C++ 实用趣味小程序
  19. 一文搞懂保险的前世今生,说实话,每个人其实都需要保险
  20. C语言计算5+55+555+5555+55555

热门文章

  1. C++ 系列:基础知识储备
  2. ThinkPHP集成万象优图
  3. Java基础03 构造器与方法重载
  4. 64位以内Rabin-Miller 强伪素数测试和Pollard rho 因数分解解析
  5. 选择 Reac​​tJS 的五大理由
  6. jQuery 对AMD的支持(Require.js中如何使用jQuery)
  7. 第十六课、Qt对象间的父子关系------------------狄泰软件学院
  8. 读取excel文件内容代码
  9. 【转】ofbiz数据库表结构设计
  10. 26Exchange Server 2010跨站点部署-内外网邮件流测试