算法 std::for_each()
要求它的第三个参数是一个仅接受正好一个参数的函数或函数对象。 如果 std::for_each()
被执行,指定容器中的所有元素 - 在上例中,这些元素的类型为 int
- 将按顺序被传入至 print()
函数。 但是,如果要使用一个具有不同签名的函数的话,事情就复杂了。 例如,如果要传入的是以下函数 add()
,它要将一个常数值加至容器中的每个元素上,并显示结果。
- void add(int i, int j)
- {
- std::cout << i + j << std::endl;
- }
由于 std::for_each()
要求的是仅接受一个参数的函数,所以不能直接传入 add()
函数。 源代码必须要修改。
以上程序将值10加至容器 v 的每个元素之上,并使用标准输出流显示结果。 源代码必须作出大幅的修改,以实现此功能:add()
函数已被转换为一个派生自 std::binary_function
的函数对象。
- #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(1);
- v.push_back(3);
- v.push_back(2);
- std::for_each(v.begin(), v.end(), boost::bind(add, 10, _1));
- }
象 add()
这样的函数不再需要为了要用于 std::for_each()
而转换为函数对象。 使用 boost::bind()
,这个函数可以忽略其第一个参数而使用。
因为 add()
函数要求两个参数,两个参数都必须传递给 boost::bind()
。 第一个参数是常数值10,而第二个参数则是一个怪异的 _1。
1_ 被称为占位符(placeholder),定义于 Boost.Bind。 除了 1,Boost.Bind 还定义了 __2 和 3_。 通过使用这些占位符,boost::bind()
可以变为一元、二元或三元的函数。 对于 1_, boost::bind()
变成了一个一元函数 - 即只要求一个参数的函数。 这是必需的,因为 std::for_each()
正是要求一个一元函数作为其第三个参数。
下面这个例子通过 boost::bind()
定义了一个二元函数,用于 std::sort()
算法,该算法要求一个二元函数作为其第三个参数。
因为使用了两个占位符 1_ 和 2,所以 boost::bind()
定义了一个二元函数。 std::sort()
算法以容器 _v 的两个元素来调用该函数,并根据返回值来对容器进行排序。 基于 compare()
函数的定义,容器将被按降序排列。
但是,由于 compare()
本身就是一个二元函数,所以使用 boost::bind()
确是多余的。
- #include <boost/bind.hpp>
- #include <vector>
- #include <algorithm>
- {
- return i > j;
- }
- int main()
- {
- std::vector<int> v;
- v.push_back(1);
- v.push_back(3);
- v.push_back(2);
- std::sort(v.begin(), v.end(), compare);
- }
该例子仅改变了占位符的顺序:2_ 被作为第一参数传递,而 1_ 则被作为第二参数传递至 compare()
,这样即可改变排序的顺序。