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. python中将12345转换为54321

    #将12345转换为54321 a = 12345789 ret = 0 #当a不为零的时候,循环条件为true,执行语句块 while a : #对a求余数,第一次循环则把5求出来 last = a ...

  2. mui初级入门教程(三)— html5+ XMLHttpRequest 与mui ajax用法详解

    文章来源:小青年原创发布时间:2016-05-29关键词:mui,html5+,XMLHttpRequest,ajax,懒加载转载需标注本文原始地址: http://zhaomenghuan.gith ...

  3. Scala从入门到放弃(三)Scala的数组、映射、元组和集合

    1.数组 1.1定长数组和变长数组 object ArrayDemo { def main(args: Array[String]): Unit = { //初始化一个长度为8的定长数组,其数组元素均 ...

  4. Windows7系统C盘空间不足

    C盘要满了,用WizTree发现:;两个大文件, ①睡眠有关的,用命令提示符(管理员身份运行), 命令窗口中输入 powercfg -h off,即可关闭休眠功能,同时 Hiberfil.sys 文件 ...

  5. python判断list中是否包含某个元素

    python判断list中是否包含某个元素 theList = ['a','b','c'] if 'a' in theList: print 'a in the list' if 'd' not in ...

  6. Centos7.6 安装

    序:在“Intel 英特尔 NUC6I7KYK 迷你主机” 上 安装“Centos7.6” 一.制作U盘启动盘 参考<制作CentOS的U盘启动盘>.<制作 CentOS7的U盘系统 ...

  7. 015-Spring Boot 定制和优化内嵌的Tomcat

    一.内嵌web容器 参看http://www.cnblogs.com/bjlhx/p/8372584.html 查看源码可知提供以下三种: 二.定制优化tomcat 2.1.配置文件配置 通过appl ...

  8. java.io.IOException: Malformed \uxxxx encoding.

    java.io.IOException: Malformed \uxxxx encoding.  at com.dong.frame.util.ReadProperties.read(ReadProp ...

  9. mybatis批量插入、更新和删除

    https://blog.csdn.net/m0_37981235/article/details/79131493 https://www.jb51.net/article/132823.htm

  10. php不支持多线程怎么办

    PHP 默认并不支持多线程,要使用多线程需要安装 pthread 扩展,而要安装 pthread 扩展,必须使用 --enable-maintainer-zts 参数重新编译 PHP,这个参数是指定编 ...