Beyond the C++ Standard Library: An Introduction to Boost -- Library 11.1 Function

Library 11. Function

 

Function 库如何改进你的程序?

  • 保存函数指针和函数对象,用于后续的调用

在进行回调的设计中,常常需要保存函数和函数对象,而且某些函数或类也是通过函数指针或函数对象来配制其客户化功能。通常,函数指针用于实现回调及延时函数。但是,仅仅使用函数指针会有很多限制,更好的方法是采用泛型机制来定义要被保存的函数的署名特征,而让调用者来决定提供哪一种的类函数实体(函数指针或函数对象)。这样就可以使用任何行为类似于函数的东西,例如,使用 Boost.Bind Boost.Lambda 的返回结果。这意味着可以给这些被保存的函数增加状态(因为函数对象是一种类)。这种泛化由 Boost.Function 提供。这个库用于保存并然后调用函数或函数对象。

 

Function 如何适用于标准库?

本库提供了当前标准库所不具备的功能。泛型回调是对商业逻辑的表示层进行解耦的所有框架都会有的非常自然的组成部分,并且常被用到。由于C++标准库不支持保存函数指针和函数对象以供稍后的调用,因此这个工具为标准库提供了非常重要的扩展。而且,本库完全兼容于标准库的绑定器(bind1st bind2nd),就象前面所讨论过的其它绑定器一样,如 Boost.Bind Boost.Lambda.

 

Function

头文件: "boost/function.hpp"

头文件 "function.hpp" 包含了带有从0到10个参数的函数原型(这是实现所定义的,在当前实现中缺省的上限就是10[1])。你也可以根据你的需要,只包含相应参数数量的头文件,文件名为 "function/functionN.hpp", 其中N可以从0到10。Boost.Function有两种不同的接口,其中一种的好处在于它的语法接近于函数声明(而且不要求函数的签名包含参数的数量),另一种接口的好处在于可以在多个编译器中工作。选择哪一种接口,至少部分地取决于你使用的编译器。如果可以,就使用我们称为首选语法(preferred syntax)的那种。在本章中,两种格式都会用到。

[1] Boost.Function 可以配置为支持多达127个参数。

使用首选语法的声明

一个 function 的声明包括该 function 所兼容的函数或函数对象的签名以及返回类型。结果以及参数的类型以单个参数的方式全部提供给模板。例如,声明一个 function ,它返回 bool 并接受一个类型 int 的参数,如下:

boost::function<bool (int)> f;

可以在括号中给出参数列表,以逗号分隔,就象普通的函数声明一样。所以,声明一个没有返回值(void)并带有类型分别为 intdouble 的两个参数的函数,就象这样:

boost::function<void (int,double)> f;
使用兼容语法的声明

声明 functions 的第二种方法是,分别给出函数调用的返回类型及参数类型作为模板类型参数。并且,要在 function 类的名字中加上后缀,后缀是一个表示 function 可接受的参数数量的整数。例如,声明一个返回 bool 并接受一个类型 int 的参数的函数,方法如下:

boost::function1<bool,int> f;

这里的数字是对应函数可接受的参数数量,在上例中有一个参数(int),所以是 function1 。更多的参数就意味着要给出更多的模板类型参数并且改变这个数字后缀。一个 function ,返回 void 并接受类型为 intdouble 的两个参数,如下:

boost::function2<void,int,double> f;

事实上,这个库由一组类组成,其中每个类带有不同数量的参数。如果包含头文件 "function.hpp" 就无需关心这一点,但如果包含带数字的头文件,你就必须包含正确数字的头文件。

首选语法更容易阅读,也更象在声明一个函数,所以你应该尽可能使用它。不幸的是,虽然首选语法是完全合法的C++并且更易读,但是还不是所有编译器都可以支持它。如果你的编译器正好不能处理这种语法,你就必须使用另一种格式。如果你需要编写最大兼容性的代码,你也只能选择使用另一种格式。让我们来看一下 function 的接口中最重要的部分。

成员函数
function(); 

缺省构造函数创建一个空的函数对象。如果一个空的 function 被调用,将会抛出一个类型为 bad_function_call 的异常。

template <typename F> function(F g); 

这个泛型的构造函数接受一个兼容的函数对象,即这样一个函数或函数对象,它的返回类型与被构造的 function 的返回类型或者一样,或者可以隐式转换,并且它的参数也要与被构造的 function 的参数类型或者一样,或者可以隐式转换。注意,也可以使用另外一个 function 实例来进行构造。如果这样做,并且 function f 为空,则被构造的 function 也为空。使用空的函数指针和空的成员函数指针也会产生空的 function

template <typename F> function(reference_wrapper<F> g); 

这个构造函数与前一个类似,但它接受的函数对象包装在一个 reference_wrapper 中,这用以避免通过值来传递而产生函数或函数对象的一份拷贝。这同样要求函数对象兼容于 function 的签名。

function& operator=(const function& g); 

赋值操作符保存 g 中的函数或函数对象的一份拷贝;如果 g 为空,被赋值的函数也将为空。

template<typename F> function& operator=(F g); 

这个泛型赋值操作符接受一个兼容的函数指针或函数对象。注意,也可以用另一个 function 实例(带有不同但兼容的签名)来赋值。这同样意味着,如果 g 是另一个 function 实例且为空,则赋值后的函数也为空。赋值一个空的函数指针或空的成员函数指针也会使 function 为空。

bool empty() const;

这个成员函数返回一个布尔值,表示该 function 是含有一个函数/函数对象或是为空。如果有一个目标函数或函数对象可被调用,它返回 false 。因为一个 function 可以在一个布尔上下文中测试,或者与0进行比较,因此这个成员函数可能会在未来版本的库中被取消,你应该避免使用它。

void clear(); 

这个成员函数清除 function, 即它不再关联到一个函数或函数对象。如果 function 已经是空的,这个调用没有影响。在调用后,function 肯定为空。令一个 function 为空的首选方法是赋0给它;clear 可能在未来版本的库中被取消。

operator safe_bool() const 

这个转型函数返回一个未指定类型(由 safe_bool 表示),它可以用于布尔上下文中。如果 function 为空,返回值为 false. 如果 function 中保存了一个函数指针或函数对象,则返回值为 true. 注意,使用一个不同于 bool 的类型,可以使得这个转型函数十分安全且不会被重载干扰,同时还提供了直接在布尔上下文中测试 function 实例的惯用法。它等同于表达式 !!f, 其中 f 为一个 function 实例。

result_type operator()(Arg1 a1, Arg2 a2, ..., ArgN aN) const; 

调用操作符是调用 function 的方法。你不能调用一个空的 function ,那样会抛出一个 bad_function_call 异常,即当 !f.empty(), if (f), 或 if (!!f) 返回 true 时。调用操作符的执行会调用 function 中的函数或函数对象,并返回它的结果。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值