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中用os.walk查找全部的子文件

    import os import shutil # 要遍历查找的文件所在的父文件夹 trajectory_filename =r"D:\mapping" # 要粘贴到的目标文件夹 ...

  2. Linux┊详解udev

    是一小部分例子,如果你的系统采用了udev方式,那你应该可以看到更多的规则.如果你想修改设备的权限或者创建信的符号连接,那么你需要熟读这些规则,特别是要仔细注意你修改的那些与之相关的设备. 修改你的u ...

  3. linux sed如何锁定某一行数据进行替换

  4. pandas melt 与pivot 函数

    (掌握这个,基本就完美无缺的任意按照自己的想法,更改列了.) 背景: 最近有个excel 数据需要转化的过程. 数据量还挺大的,大概有30多万. 需要把某些行变成列,有些列又变成行. 这个操作本身就比 ...

  5. Mac环境搭建nginx服务器

    一 安装 1 安装Homebrew macOS 缺失的软件包的管理器,安装方法参考官网.(可能被墙) 2 安装nginx. brew install nginx 先更新homebrew.再安装ngin ...

  6. Optimal Value Functions and Optimal Policy

    Optimal Value Function is how much reward the best policy can get from a state s, which is the best ...

  7. 基于Apache搭建HTTP HTTPS

    参考资料 <openssl攻略>--第一章 <Apache服务器配置与使用工作笔记>-- 第六章 第十四章 https://juejin.im/post/5a31faf2518 ...

  8. Python判断端口连通性

    #!/usr/bin/env python # -*- coding: utf-8 -*- import socket,sys def MySQL_Connet(MySQL_ip): MySQL_so ...

  9. selenium python 报错“ unable to find binary in default location”

    selenium python 报错如下: raise exception_class(message, screen, stacktrace)selenium.common.exceptions.W ...

  10. [Linux] 005 Linux 常见目录的作用及一些注意事项

    1. Linux 常见目录及其作用 目录名 作用 /bin/ 存放系统命令的目录普通用户各超级用户都可以执行放在 /bin 下的命令在单用户模式下也可以执行 /sbin/ 保存和系统环境相关的命令只有 ...