In functional programming, functions are objects and can be processed like objects. With Boost.Phoenix, it is possible for a function to return another function as a result. It is also possible to pass a function as a parameter to another function. Because functions are objects, it's possible to distinguish between instantiation and execution. Accessing a function isn't equal to executing it.

Boost.Phoenix supports functional programming with function objects: Functions are objects based on classes which overload the operator(). That way function objects behave like other objects in c++. For example, they can be copied and stored in a container. However, they also behave like functions because they can be called.

1. phoenix

#include <boost/phoenix/phoenix.hpp>
#include <vector>
#include <algorithm>
#include <iostream> bool is_odd(int i) { return i % == ; } int main()
{
std::vector<int> v{, , , , }; std::cout << std::count_if(v.begin(), v.end(), is_odd) << std::endl; auto lambda = [](int i){ return i % == ; };
std::cout << std::count_if(v.begin(), v.end(), lambda) << std::endl; using namespace boost::phoenix::placeholders;
auto phoenix = arg1 % == ;
std::cout << std::count_if(v.begin(), v.end(), phoenix) << std::endl;
  std::vector<long> v2;
v2.insert(v2.begin(), v.begin(), v.end());
auto phoenix = arg1 % 2 == 1;
std::cout << std::count_if(v.begin(), v.end(), phoenix) << '\n';
std::cout << std::count_if(v2.begin(), v2.end(), phoenix) << '\n';
return ; }

The Phoenix function differs from free-standing and lambda functions because it has no frame. While the other two functions have a function header with a signature, the Phoenix function seems to consist of a function body only. The crucial component of the Phoenix function is boost::phoenix::placeholders::arg1. arg1 is a global instance of a function object.

arg1 is used to define an unary function. The expression arg1 % 2 == 1 creates a new function that expects one parameter. The function isn’t executed immediately but stored in phoenix. phoenix is passed to std::count_if() which calls the predicate for every number in v.

Phoenix function parameters have no types. The lambda function lambda expects a parameter of type int. The Phoenix function phoenix will accept any type that the modulo operator can handle. Think of Phoenix functions as function templates. Like function templates, Phoenix functions can accept any type.

You can think of Phoenix functions as C++ code that isn’t executed immediately. The Phoenix function in example above looks like a condition that uses multiple logical and arithmetic operators. However, the condition isn’t executed immediately. It is only executed when it is accessed from within std::count_if(). The access in std::count_if() is a normal function call.

2. boost::phoenix::val()

#include <boost/phoenix/phoenix.hpp>
#include <vector>
#include <algorithm>
#include <iostream> int main()
{
std::vector<int> v{, , , , }; using namespace boost::phoenix;
using namespace boost::phoenix::placeholders;
auto phoenix = arg1 > val() && arg1 % val() == val();
std::cout << std::count_if(v.begin(), v.end(), phoenix) << std::endl;

std::cout << arg1(1, 2, 3, 4, 5) << std::endl;
auto v = boost::phoenix::val(2);
std::cout << v() << std::endl;
return ; }

boost::phoenix::val() returns a function object initialized with the values passed to boost::phoenix::val(). The acutal type of the function object dosen't matter.

arg1 is an instance of a function object. It can be used directly and called like a function. You can pass as many parameters as you like - arg1 returns the first one.

val() is a function to create an instance of a function object. The function object is initialized with the value passed as a parameter. Is the instance is accessed like a function, the value is returned.

3. create your own phoenix functions

#include <boost/phoenix/phoenix.hpp>
#include <vector>
#include <algorithm>
#include <iostream> struct is_odd_impl
{
typedef bool result_type; template <typename T>
bool operator()(T t) const { return t % == ; }
}; boost::phoenix::function<is_odd_impl> is_odd; int main()
{
std::vector<int> v{, , , , }; using namespace boost::phoenix::placeholders;
std::cout << std::count_if(v.begin(), v.end(), is_odd(arg1)) << std::endl;
return ;
}

Class should overload the operator operator(): when an odd number is passed in, the operator returns true. Please note that you must define the type result_type. Boost.Phoenix uses it to detect the type of the return value of the operator operator().

4. transform

#include <boost/phoenix/phoenix.hpp>
#include <vector>
#include <algorithm>
#include <iostream> bool is_odd_function(int i) { return i % == ; } BOOST_PHOENIX_ADAPT_FUNCTION(bool, is_odd, is_odd_function, )

bool is_odd(int i) {
return i % 2 == 1;
}
int main()
{
std::vector<int> v{, , , , };
using namespace boost::phoenix;
using namespace boost::phoenix::placeholders;
std::cout << std::count_if(v.begin(), v.end(), is_odd(arg1)) << std::endl;
 std::cout << std::count_if(v.begin(), v.end(), bind(is_odd, arg1)) << std::endl;
return ; }

Use the macro BOOST_PHOENIX_ADAPT_FUNCTION to turn a free-standing function into a Phoenix function. Pass the type of the return value, the name of the Phoenix function to define, the name of the free-standing function, and the number of parameters to the macro.

boost phoenix的更多相关文章

  1. boost 的函数式编程库 Phoenix入门学习

    这篇文章是我学习boost phoenix的总结. 序言 Phoenix是一个C++的函数式编程(function programming)库.Phoenix的函数式编程是构建在函数对象上的.因此,了 ...

  2. boost::spirit unicode 简用记录

    本文简单记录使用boost::spirit解析有中文关键字的字符串并执行响应动作,类似于语法分析+执行. 关键字:字符串解析 boost::spirit::qi::parse qi::unicode: ...

  3. 一个c++剧情脚本指令系统

    项目希望能够实现一些剧情动画,类似角色移动,镜头变化,台词展现等.剧情动画这东西随时需要修改调整,不能写死在代码里.考虑之后认为需要做一个简单的DSL来定制剧情脚本,策划在脚本里按顺序写入命令,然后我 ...

  4. 译:Boost Property Maps

    传送门:Boost Graph Library 快速入门 原文:Boost Property Map 图的抽象数学性质与它们被用来解决具体问题之间的主要联系就是被附加在图的顶点和边上的属性(prope ...

  5. Boost简介

    原文链接:  吴豆豆http://www.cnblogs.com/gdutbean/archive/2012/03/30/2425201.html Boost库 Boost库是为C++语言标准库提供扩 ...

  6. Boost 1.61.0 Library Documentation

    http://www.boost.org/doc/libs/1_61_0/ Boost 1.61.0 Library Documentation Accumulators Framework for ...

  7. boost库的安装,使用,介绍,库分类

    1)首先去官网下载boost源码安装包:http://www.boost.org/ 选择下载对应的boost源码包.本次下载使用的是 boost_1_60_0.tar.gz (2)解压文件:tar - ...

  8. C++ Boost库分类总结

    c# 程序员写c++,各种不适应.尤其是被内存操作和几十种字符串类型的转换,简直疯了,大小写转换竟然要手动写代码实现. Boost看介绍不错,也不知道能不能跨平台.过几天要上linux写c++, 也不 ...

  9. 小试 boost spirit

    解释文本文件是日常编程中太平常的一件事情了,一般来说,土鳖点的做法可以直接手写 parser 用循环暴力地去 map 文本上的关键字从而提取相关信息,想省力一点则可以使用 tokenizer 或正则表 ...

随机推荐

  1. Vue+webpack+Element 兼容问题总结

    项目中用到了Vue.js和Elenment-UIVue官方文档中给出明确范围:Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性.但它支持所有 ...

  2. Advanced search keywords

    Advanced search options Find what you're looking for in less time. Use the following symbols to quic ...

  3. ruby异常处理

    begin # 这段代码抛出的异常将被下面的 rescue 子句捕获 rescue # 这个块将捕获所有类型的异常 retry # 这将把控制移到 begin 的开头 end

  4. Python模块学习之xlrd、xlutils、openpyxl 读写/追加Excel文件

    Python操作Excel的四个工具包 xlrd: 对Excel进行读相关操作,注意只能操作 .xls xlwt: 对Excel进行写相关操作,注意只能操作 .xls,且只能创建一个全新的Excel然 ...

  5. SVN 忽略添加文件和文件夹

    你添加的文件和文件夹是没有加入版本控制的,是你新添加的,接下来的设置才有用 忽略这个文件的方式有两种 第一种方式 添加svn:ignore    右键文件-->TortoiseSvn--> ...

  6. php用什么软件编程

    准备好好学习学习PHP了吗?那么你首先应该考虑用什么开发工具(IDE).市面上有很多这类工具,收费的有,免费的也有,选择起来并不轻松. 如果你说PHP编程用基础的文本编辑软件就可以了,比如用记事本.是 ...

  7. python网络编程中互斥锁与进程之间的通信

    一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...

  8. 线上服务器CPU100%排查

    某服务器上部署了若干tomcat实例,即若干垂直切分的Java站点服务,以及若干Java微服务,突然收到运维的CPU异常告警. 问:如何定位是哪个服务进程导致CPU过载,哪个线程导致CPU过载,哪段代 ...

  9. kmp(前缀出现次数next应用)

    http://acm.hdu.edu.cn/showproblem.php?pid=3336 Count the string Time Limit: 2000/1000 MS (Java/Other ...

  10. Go语言_方法和接口

    方法和接口 本节课包含了方法和接口,可以用这种构造来定义对象及其行为. Go 作者组编写,Go-zh 小组翻译. https://tour.go-zh.org/methods/1 方法 Go 没有类. ...