Boost C++ 库

...世界上最受推崇和专业设计的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ 编码标准

改进的函数对象适配器

头文件 functional.hpp 提供了对 C++ 标准库(第 20.3.5 节至 20.3.8 节)中指定的函数对象适配器的增强功能。 这些增强功能主要得益于两个变化:

  1. 我们使用 Boostcall_traits模板来避免 引用引用的问题,并提高 参数传递的效率。
  2. 我们使用两个 函数对象特性类模板来避免对ptr_fun在本库的适配器中使用。

目录

该头文件包含以下函数和类模板:

函数对象特性 unary_traits
binary_traits
用于确定函数对象和函数参数的类型。 消除对以下内容的需求:ptr_fun.
取反器 unary_negate
binary_negate
not1
not2
基于标准第 20.3.5 节。
绑定器 binder1st
binder2nd
bind1st
bind2nd
基于标准第 20.3.6 节。
指向函数的指针的适配器 pointer_to_unary_function
pointer_to_binary_function
ptr_fun
基于标准第 20.3.7 节。 本库不需要使用,因为绑定器和取反器可以适配函数,但可能需要与第三方适配器一起使用。
指向成员函数的指针的适配器 mem_fun_t
mem_fun1_t
const_mem_fun_t
const_mem_fun1_t
mem_fun_ref_t
mem_fun1_ref_t
const_mem_fun_ref_t
const_mem_fun1_ref_t
mem_fun
mem_fun_ref
基于标准第 20.3.8 节。

用法

使用这些适配器应该与使用标准函数对象适配器非常相似; 唯一的区别是您需要编写boost:而不是std:, 并且您会遇到更少的麻烦。

例如,假设您有一个Person类,其中包含一个set_name函数

class Person
{
  public:
    void set_name(const std::string &name);
  // ...
};

您可以重命名集合中的一群人,c,通过编写

std::for_each(c.begin(), c.end(), 
              boost::bind2nd(boost::mem_fun_ref(&Person::set_name), "Fred"));

如果使用标准适配器,则此代码通常会编译失败,因为set_name接受引用参数。 请参阅 绑定器文档中的注释,以解释为什么会这样。

编译器兼容性

头文件和 测试程序已使用以下编译器编译:

编译器 注释
Borland C++Builder 4 Update 2 没有已知问题。
Borland C++ 5.5 没有已知问题。
g++ 2.95.2 没有已知问题。
Microsoft Visual C++ Service Pack 3 编译器缺少部分特化,因此此库提供的功能比标准适配器提供的功能多不了多少
  • call_traits机制无法阻止引用引用,因此本库中的适配器将在更少的情况下可用。
  • function_traits机制无法确定函数的参数和结果类型,因此ptr_fun仍然需要使用 来适配函数。

未来方向

本库的主要重点是解决引用引用的问题,同时尽可能保持与标准库的兼容性。 这使您可以在当今的许多编译器上使用您在书籍和杂志中读到的技术。

从长远来看,可能会有更好的解决方案

  1. 几位 Boost 成员正在开发表达式模板库。 这些库将允许更自然的语法来组合和适配函数。 由于这是一项新技术,因此可能需要一段时间才能成熟并获得主要编译器的广泛支持,但前景广阔。 与此同时,functional.hpp 库填补了空白。
  2. 标准委员会已经认识到模板实例化期间发生的引用引用问题,并已着手修复标准(请参阅 C++ 标准核心语言活动问题列表)。

作者

Mark Rodgers

致谢

感谢 John Maddock 提出了使函数对象特性能够正确工作的机制。 Jens Maurer正式审查过程中提供了宝贵的反馈。


Valid HTML 4.01 Transitional

修订日期2006 年 12 月 2 日

版权所有 © 2000 Cadenza New Zealand Ltd.

根据 Boost 软件许可协议 1.0 版分发。(请参阅随附文件 LICENSE_1_0.txt 或在 https://boost.ac.cn/LICENSE_1_0.txt 复制)