文章目录
- bind
- ref函数
- Function
- Lambda
本章介绍的是函数对象,可能称为’高阶函数’更为适合。 它实际上是指那些可以被传入到其它函数或是从其它函数返回的一类函数。 在C++中高阶函数是被实现为函数对象的,所以这个标题还是有意义的。
bind
和C++中的 std::bind()用法基本一致 现在更推荐用C++的bind函数 可以通过绑定函数的方式 去指定调用
#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));
}
上面代码 将容器中的每个元素都加上10
第一个参数是常数值10,而第二个参数则是一个怪异的 _1。
_1 被称为占位符(placeholder),定义于 Boost.Bind。 除了 _1,Boost.Bind 还定义了 _2 和 _3。 通过使用这些占位符,boost::bind() 可以变为一元、二元或三元的函数。 对于 _1, boost::bind() 变成了一个一元函数 - 即只要求一个参数的函数。
这是必需的,因为 std::for_each() 正是要求一个一元函数作为其第三个参数。
当这个程序执行时,std::for_each() 对容器 v 中的第一个元素调用该一元函数。 元素的值通过占位符 _1 传入到一元函数中。 这个占位符和常数值被进一步传递到 add() 函数。 通过使用这种机制,std::for_each() 只看到了由 boost::bind() 所定义的一元函数。 而 boost::bind() 本身则只是调用了另一个函数,并将常数值或占位符作为参数传入给它。
ref函数
#include <boost/bind.hpp>
#include <iostream>
#include <vector>
#include <algorithm>
void add(int i, int j, std::ostream &os)
{
os << 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, boost::ref(std::cout)));
}
不过这一次该函数需要一个流对象的引用来打印信息。 因为传给 boost::bind() 的参数是以值方式传递的,所以 std::cout 不能直接使用,否则该函数会试图创建它的一份拷贝。
通过使用模板函数 boost::ref(),象 std::cout 这样的流就可以被以引用方式传递,也就可以成功编译上面这个例子了。
原因:因为std::ostream对象不能被复制,只能被引用。 代码实际上在尝试做一件编译器不允许的事情:将非常量引用绑定到一个临时对象上(尽管在这个特定情况下,std::cout本身不是临时的,但问题的根源在于如何传递引用)。
boost::ref 是 Boost 库中的一个实用工具,它主要用于解决在函数对象作为参数传递时可能出现的拷贝代价过高、不希望拷贝对象或禁止拷贝对象的问题。boost::ref 可以将一个对象包装成一个引用,从而在传递参数时消除对象拷贝的代价,或者将不可拷贝的对象变为可以通过引用方式传递。
Function
C++也有这部分功能 用法如下
#include <functional>
#include <iostream>
using namespace std;
using customfun = function<int(const char*)>;
int func(const char* name)
{
return strlen(name);
}
int main()
{
customfun f= func;
cout << f("misW") << endl;
}
boost 部分
#include <boost/function.hpp>
#include <iostream>
#include <cstdlib>
#include <cstring>
int main()
{
boost::function<int (const char*)> f = std::atoi;
std::cout << f("1609") << std::endl;
f = std::strlen;
std::cout << f("1609") << std::endl;
}
基本一致
Lambda
和C++部分基本一致 更推荐C++的用法