boost phoenix
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的更多相关文章
- boost 的函数式编程库 Phoenix入门学习
这篇文章是我学习boost phoenix的总结. 序言 Phoenix是一个C++的函数式编程(function programming)库.Phoenix的函数式编程是构建在函数对象上的.因此,了 ...
- boost::spirit unicode 简用记录
本文简单记录使用boost::spirit解析有中文关键字的字符串并执行响应动作,类似于语法分析+执行. 关键字:字符串解析 boost::spirit::qi::parse qi::unicode: ...
- 一个c++剧情脚本指令系统
项目希望能够实现一些剧情动画,类似角色移动,镜头变化,台词展现等.剧情动画这东西随时需要修改调整,不能写死在代码里.考虑之后认为需要做一个简单的DSL来定制剧情脚本,策划在脚本里按顺序写入命令,然后我 ...
- 译:Boost Property Maps
传送门:Boost Graph Library 快速入门 原文:Boost Property Map 图的抽象数学性质与它们被用来解决具体问题之间的主要联系就是被附加在图的顶点和边上的属性(prope ...
- Boost简介
原文链接: 吴豆豆http://www.cnblogs.com/gdutbean/archive/2012/03/30/2425201.html Boost库 Boost库是为C++语言标准库提供扩 ...
- Boost 1.61.0 Library Documentation
http://www.boost.org/doc/libs/1_61_0/ Boost 1.61.0 Library Documentation Accumulators Framework for ...
- boost库的安装,使用,介绍,库分类
1)首先去官网下载boost源码安装包:http://www.boost.org/ 选择下载对应的boost源码包.本次下载使用的是 boost_1_60_0.tar.gz (2)解压文件:tar - ...
- C++ Boost库分类总结
c# 程序员写c++,各种不适应.尤其是被内存操作和几十种字符串类型的转换,简直疯了,大小写转换竟然要手动写代码实现. Boost看介绍不错,也不知道能不能跨平台.过几天要上linux写c++, 也不 ...
- 小试 boost spirit
解释文本文件是日常编程中太平常的一件事情了,一般来说,土鳖点的做法可以直接手写 parser 用循环暴力地去 map 文本上的关键字从而提取相关信息,想省力一点则可以使用 tokenizer 或正则表 ...
随机推荐
- MYSQL之union和order by分析([Err] 1221 - Incorrect usage of UNION and ORDER BY)
我在一个业务中采用了按月的分表策略,当查询的条件跨月的时候,使用了union all汇总2个表的数据,并按插入时间倒序排列.查询并不复杂,但是当执行的时候却报错了. SELECT * FROM `ta ...
- HDU6668 Polynomial(模拟)
HDU6668 Polynomial 顺序遍历找出最高次幂项的系数 分三种情况 \(1/0\).\(0/1\).\(f(x)/g(x)\) . 复杂度为 \(O(n)\) . #include< ...
- SqlServer 字段类型详解
bit 整型 bit数据类型是整型,其值只能是0.1或空值.这种数据类型用于存储只有两种可能值的数据,如Yes 或No.True 或False .On 或Off. 注意:很省空间的一种数据类型, ...
- Maven系列学习(一)Maven基本知识
Maven 简介 1.Maven主要是基于Java平台的项目构建,依赖管理和项目信息 2.Maven是优秀的构建工具,跨平台,消除构建的重复,抽象了一个完整的构建生命周期模型,标准化构建过程 3.管理 ...
- 二叉树BinTree4种遍历及其应用
前序遍历 template<class T> void BinTree<T>::PreOrder(BinTreeNode<T>*subTree){ //前序遍历以s ...
- Ecshop 商品详情页如何添加立即购买按钮
1,加到位置 <li class="add_cart_li"> <a href="javascript:addToCart1({$goods.goods ...
- C# 使用Silverlight打印图片
原文:https://www.cnblogs.com/jiajiayuan/archive/2012/04/13/2444246.html Silverlight中的打印只有一个类,那就是PrintD ...
- zabbix4.0短信告警配置
#!/usr/bin/env python3 import requests import sys #http://utf8.api.smschinese.cn/?Uid=USERNAME&K ...
- Android生命周期例子小解
Activity 从创建到进入运行态所触发的事件 onCreate()-->onStart-->onResume() 从运行态到停止态所触发的事件 onPa ...
- Error: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimizat
按照教程上配置文件如下: var webpack=require('webpack'); var HtmlwebpackPlugin=require('html-webpack-plugin'); v ...