Boost.Bind是一个库,它简化和概括了最初需要std::bind1st()和std::bind2nd()的功能
示例 1.1:具有兼容函数的std::for_each()
#include <vector>
#include <algorithm>
#include <iostream>
void print(int i)
{
std::cout << i << '\n';
}
int main()
{
std::vector<int> v{1, 3, 2};
std::for_each(v.begin(), v.end(), print);
}
std::for_each()的第三个参数是需要唯一参数的函数或函数对象。在示例 1.1中,std::for_each()将容器 v 中的数字作为唯一参数一个接一个地传递给 print()。
如果你需要传入一个签名不符合算法要求的函数,那就更难了。例如,如果您希望print()接受输出流作为附加参数,则不能再将其与std::for_each()一起使用。
例 1.2。std::for_each()与std::bind1st()
#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
class print : public std::binary_function<std::ostream*, int, void>
{
public:
void operator()(std::ostream *os, int i) const
{
*os << i << '\n';
}
};
int main()
{
std::vector<int> v{1, 3, 2};
std::for_each(v.begin(), v.end(), std::bind1st(print{}, &std::cout));
}
与示例 1.1一样,示例 1.2将 v 中的所有数字写入标准输出。但是,这一次,输出流作为参数传递给 print()。为此,函数print()被定义为从std::binary_function派生的函数对象。
使用Boost.Bind,您无需将print()从函数转换为函数对象。相反,您使用在boost/bind.hpp中定义的函数模板boost::bind()。
例 1.3:std::for_each()和boost::bind()
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
void print(std::ostream *os, int i)
{
*os << i << '\n';
}
int main()
{
std::vector<int> v{1, 3, 2};
std::for_each(v.begin(), v.end(), boost::bind(print, &std::cout, _1));
}
示例 1.3使用 print() 作为函数,而不是函数对象。因为 print() 需要两个参数,所以函数不能直接传递给std::for_each()。相反,boost::bind()被传递给std::for_each()并且 print() 作为第一个参数被传递给boost::bind()。
由于 print() 需要两个参数,因此这两个参数也必须传递给boost::bind()。它们是指向std::cout和_1的指针。
_1是占位符。Boost.Bin d 定义了从_1到_9的占位符。这些占位符告诉boost::bind()返回一个函数对象,该对象期望与具有最大数量的占位符一样多的参数。如果像例 1.3中一样,只使用占位符_1,则boost::bind( ) 返回一个一元函数对象——一个需要唯一参数的函数对象。在这种情况下这是必需的,因为std::for_each()只传递一个参数。
std::for_each()调用一元函数对象。传递给函数对象的值——来自容器v的数字——占据占位符_1的位置。boost::bind()获取数字和指向 std::cout 的指针并将它们转发给 print()。
请注意boost::bind()与std::bind1st()和std::bind2nd()一样,按值获取参数。为了防止调用程序尝试复制std::cout, print() 需要一个指向流的指针。Boost.Ref 提供了一个允许您通过引用传递参数的函数。
示例 1.4说明了如何使用boost::bind()定义二进制函数对象。它使用算法std::sort(),它需要一个二进制函数作为它的第三个参数。
例 1.4。std::sort()与boost::bind()
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
bool compare(int i, int j)
{
return i > j;
}
int main()
{
std::vector<int> v{1, 3, 2};
std::sort(v.begin(), v.end(), boost::bind(compare, _1, _2));
for (int i : v)
std::cout << i << '\n';
}
在示例 1.4中,由于使用了占位符_2,因此创建了一个二进制函数对象。算法std::sort()使用来自容器 v 的两个值调用此二进制函数对象,并计算返回值以对容器进行排序。函数 compare() 被定义为按降序对v进行排序。
由于compare()是二进制函数,因此可以直接将其传递给std::sort()。但是,使用boost::bind()仍然有意义,因为它允许您更改参数的顺序。例如,如果您想按升序对容器进行排序但不想更改 compare() ,则可以使用boost::bind( )
例 1.5。std::sort()与boost::bind()并更改了占位符的顺序
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
bool compare(int i, int j)
{
return i > j;
}
int main()
{
std::vector<int> v{1, 3, 2};
std::sort(v.begin(), v.end(), boost::bind(compare, _2, _1));
for (int i : v)
std::cout << i << '\n';
}