#Boost# Boost 高阶函数

志扬工作室

共 5180字,需浏览 11分钟

 ·

2022-11-17 16:47

 文章所涉及内容更多来自网络,在此声明,并感谢知识的贡献者!

Boost 高阶函数

Boost高阶函数
http://zh.highscore.de/cpp/boost/functionobjects.html

C++ 标准的函数绑定


C++标准的函数绑定

#include <iostream>

#include <vector>

#include <algorithm>

void print(int i)

{

std::cout << i << 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(), print);

}

算法 std::for_each() 要求它的第三个参数是一个仅接受正好一个参数的函数或函数对象。 如果 std::for_each() 被执行,指定容器中的所有元素 - 在上例中,这些元素的类型为int - 将按顺序被传入至 print() 函数。


std::bind1st

#include <iostream>

#include <vector>

#include <algorithm>

#include <functional>

class add

: public std::binary_function<int, int, void>

{

public:

void operator()(int i, int j) const

{

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(), std::bind1st(add(), 10));

}

add() 函数已被转换为一个派生自 std::binary_function的函数对象。将值10加至容器 v 的每个元素之上,并使用标准输出流显示结果。


boost bind 绑定函数与参数


boost::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));

}

add() 这样的函数不再需要为了要用于 std::for_each() 而转换为函数对象。 使用 boost::bind(),这个函数可以忽略其第一个参数而使用。

因为 add() 函数要求两个参数,两个参数都必须传递给 boost::bind()。 第一个参数是常数值10,而第二个参数则是一个怪异的_1。

_1 被称为占位符(placeholder),定义于 Boost.Bind。 除了 _1,Boost.Bind还定义了 _2 和 _3。 通过使用这些占位符,boost::bind() 可以变为一元、二元或三元的函数。


#include <boost/bind.hpp>

#include <vector>

#include <algorithm>

bool compare(int i, int j)

{

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(), boost::bind(compare, _1, _2));

}

因为使用了两个占位符 _1 和 _2,所以boost::bind() 定义了一个二元函数。 std::sort() 算法以容器v 的两个元素来调用该函数,并根据返回值来对容器进行排序。 基于 compare()函数的定义,容器将被按降序排列。


#include <boost/bind.hpp>

#include <vector>

#include <algorithm>

bool compare(int i, int j)

{

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);

}

#include <boost/bind.hpp>

#include <vector>

#include <algorithm>

bool compare(int i, int j)

{

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(), boost::bind(compare, _2, _1));

}

如果容器要按升序排列而又不能修改 compare() 函数的定义。该例子仅改变了占位符的顺序:_2 被作为第一参数传递,而 _1 则被作为第二参数传递至 compare(),这样即可改变排序的顺序。

boost::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 这样的流就可以被以引用方式传递,也就可以成功编译上面这个例子了。


boost function 指向特定函数的指针


boost::function

#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;

}

boost::function 可以定义一个指针,指向具有特定签名的函数。 以上例子定义了一个指针 f,它可以指向某个接受一个类型为 const char* 的参数且返回一个类型为 int 的值的函数。 定义完成后,匹配此签名的函数均可赋值给这个指针。 这个例程就是先将 std::atoi() 赋值给 f,然后再将它重赋值为std::strlen()。

注意,给定的数据类型并不需要精确匹配:虽然 std::strlen() 是以std::size_t 作为返回类型的,但是它也可以被赋值给 f。

如果 f 未赋予一个函数而被调用,则会抛出一个 boost::bad_function_call 异常。


boost lambda 匿名函数


Boost.Lambda匿名函数

#include <boost/lambda/lambda.hpp>

#include <iostream>

#include <vector>

#include <algorithm>

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(), std::cout << boost::lambda::_1 << "\n");

}

Boost.Lambda 提供了几个结构来定义匿名函数。 代码就被置于执行的地方,从而省去将它包装为一个函数再进行相应的函数调用的这些开销。 与原来的例子一样,这个程序将容器 v 的所有元素写出至标准输出流。

与 Boost.Bind 相类似,Boost.Lambda也定义了三个占位符,名为 _1, _2 和 _3。 但与 Boost.Bind 不同的是,这些占位符是定义在单独的名字空间的。

虽然 Boost.Lambda 非常强大,但也有一些缺点。 要在以上例子中插入换行的话,必须用 "\n" 来替代 std::endl 才能成功编译。 因为一元 std::endl 模板函数所要求的类型不同于 lambda 函数std::cout << boost::lambda::_1 的函数,所以在此不能使用它。

#include <boost/lambda/lambda.hpp>

#include <boost/lambda/if.hpp>

#include <iostream>

#include <vector>

#include <algorithm>

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::lambda::if_then(boost::lambda::_1 > 1,

std::cout << boost::lambda::_1 << "\n"));

}

boost::lambda::if_then() 模板函数,它要求两个参数:第一个参数对条件求值 - 如果为真,则执行第二个参数。

除了boost::lambda::if_then(),Boost.Lambda,还提供了boost::lambda::if_then_else()和 boost::lambda::if_then_else_return()模板函数 - 它们都要求三个参数。 另外还提供了用于实现循环、转型操作符,甚至是 throw - 允许 lambda 函数抛出异常 - 的模板函数。

浏览 25
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报