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. 虚拟机安装linux遇到的问题

    1.运行 yum -y update,提示没有权限,改为sudo yum  -y update后,提示没有已启用的仓库.网上查找发现没有yum的库,然后开始安装yum. sudo apt-get in ...

  2. 设置Select下拉多选框功能,赋值与绑定问题

    项目需要所以更改select为多选下拉的菜单选项. 我用的是后台直接绑定 在前台aspx页面直接写一个 <div id="dropsxs" runat="serve ...

  3. RHEL7(RedHat 7)本地yum源的配置

    配置yum 源 1.挂载DVD光盘到/mnt   因为配置时候路径名里面不能有空格,否则不能识别  [root@ mnt]# mount /dev/cdrom /mnt 2.在目录/etc/yum.r ...

  4. Linux学习篇(一)-初识Linux

    开源许可协议 简单了解开源许可协议,一张图读懂. linux 系统特点 linux 特点安全性高.高可用.高性能 稳定且有效率 免费或少许免费 漏洞少且快速修补 多任务多用户 更加安全的用户及文件权限 ...

  5. 页面跳转(包括vue路由)

    1.JS实现页面跳转 1.1 使用window.location的href属性跳转 window.location.href = 'http://www.baidu.com';此处window可以省略 ...

  6. Altium Designer chapter4总结

    原理图设计进阶中需要注意如下: (1)多电路原理图的设计:图纸连接符是连接各个电路图的电器连接:VCC GND属于特殊的网络标号,在多电路原理图中不需要添加. (2)层次式电路原理图设计:注意自上而下 ...

  7. 【BASIS系列】SAP 设置系统timeout时间

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[BASIS系列]SAP 设置系统timeout ...

  8. 云计算+区块链=BaaS

    云计算+区块链=BaaS 本文来自于:https://www.toutiao.com/i6540096399017509389/ 云计算和区块链的区别 云计算现在已经是一个成熟的技术和应用了,美国国家 ...

  9. charles模拟弱网情况

    网络主要需要注意什么场景: 弱网功能测试 无网状态测试 网络切换测试 用户体验关注 下面我们使用charles测试弱网,针对不同网络下的测试 打开charles(抓包软件)  

  10. Django 无法通过request.POST.get()获取数据的问题

    原来是contentType为application/json时,Django不支持request.POST.get(),但可以通过request.body来获取string类型的参数: data = ...