什么是使用Boost.Phoenix好处? [英] What are the benefits of using Boost.Phoenix?
问题描述
我不明白什么用Boost.Phoenix的实实在在的好处。
I can not understand what the real benefits of using Boost.Phoenix.
当我与Boost.Spirit语法使用它,它真的有用:
When I use it with Boost.Spirit grammars, it's really useful:
double_[ boost::phoenix::push_back( boost::phoenix::ref( v ), _1 ) ]
当我使用它的lambda函数,它也是有用的,优雅的:
When I use it for lambda functions, it's also useful and elegant:
boost::range::for_each( my_string, if_ ( '\\' == arg1 ) [ arg1 = '/' ] );
但什么是这个库中一切的好处?文档说:函子无处不在。我不明白什么是它的好?
But what are the benefits of everything else in this library? The documentation says: "Functors everywhere". I don't understand what is the good of it?
推荐答案
我会点你出来就是Boost.Lambda和Boost.Phoenix之间的关键区别:
I'll point you out what is the critical difference between Boost.Lambda and Boost.Phoenix:
的 Boost.Phoenix支持(静态)多态仿函数,而Boost.Lambda绑定总是单态。的
(与此同时,在很多方面,两个库可以结合,所以它们不是排他性的选择。)
(At the same time, in many aspects the two libraries can be combined, so they are not exclusive choices.)
让我说明(警告:code未测试)
在凤凰城一个仿函数可以转换成凤凰懒惰的功能(从<一个href=\"http://www.boost.org/doc/libs/1_54_0/libs/phoenix/doc/html/phoenix/starter_kit/lazy_functions.html\" rel=\"nofollow\">http://www.boost.org/doc/libs/1_54_0/libs/phoenix/doc/html/phoenix/starter_kit/lazy_functions.html)
In Phoenix a functor can converted into a Phoenix "lazy function" (from http://www.boost.org/doc/libs/1_54_0/libs/phoenix/doc/html/phoenix/starter_kit/lazy_functions.html)
struct is_odd_impl{
typedef bool result_type; // less necessary in C++11
template <typename Arg>
bool operator()(Arg arg1) const{
return arg1 % 2 == 1;
}
};
boost::phoenix::function<is_odd_impl> is_odd;
is_odd
是真正的多态(如仿 is_odd_impl
)。这就是 is_odd(_1)
可在任何法案(有意义)。例如,在 is_odd(_1)(2U)==真
和 is_odd(_1)(1-21)==真
。 is_odd
可以组合成一个更复杂的前pression而不丧失其多态
is_odd
is truly polymorphic (as the functor is_odd_impl
). That is is_odd(_1)
can act on anything (that makes sense). For example in is_odd(_1)(2u)==true
and is_odd(_1)(2l)==true
. is_odd
can be combined into a more complex expression without losing its polymorphic behavior.
什么是我们可以得到这Boost.Lambda最接近?我们可以定义两个重载:
What is the closest we can get to this in Boost.Lambda?, we could defined two overloads:
bool is_odd_overload(unsigned arg1){return arg1 % 2 == 1;}
bool is_odd_overload(long arg1){return arg1 % 2 == 1;}
而是要创造一个lambda懒功能,我们将不得不选择其中的两个:
but to create a Lambda "lazy function" we will have to choose one of the two:
using boost::lambda::bind;
auto f0 = bind(&is_odd_overload, _1); // not ok, cannot resolve what of the two.
auto f1 = bind(static_cast<bool(*)(unsigned)>(&is_odd_overload), _1); //ok, but choice has been made
auto f2 = bind(static_cast<bool(*)(long)>(&is_odd_overload), _1); //ok, but choice has been made
即使我们定义了一个模板版本
Even if we define a template version
template<class T>
bool is_odd_template(T arg1){return arg1 % 2 == 1;}
,我们将具有结合到模板函数的一个特定实例,例如
we will have to bind to a particular instance of the template function, for example
auto f3 = bind(&is_odd_template<unsigned>, _1); // not tested
无论是 F1
也不 F2
也不 F3
是真正的由于选择的多态已在结合的时间作出的。
Neither f1
nor f2
nor f3
are truly polymorphic since a choice has been made at the time of binding.
(注:这未必是最好的例子,因为事情似乎由于从符号长隐式转换工作,但那是另一回事)
(Note1: this may not be the best example since things may seem to work due to implicit conversions from unsigned to long, but that is another matter.)
要总结,给出一个多态函数/仿函数的lambda不能绑定到多态函数(据我所知),而菲尼克斯可以。的确,凤凰卫视依靠结果协议 http://www.boost.org/doc/libs/1_54_0/libs/utility/utility.htm#result_of 但1)至少是可能的,2)这是在C少的问题++ 11,在那里返回类型很容易推断,它可以自动地完成。
To summarize, given a polymorphic function/functor Lambda cannot bind to the polymorphic function (as far as I know), while Phoenix can. It is true that Phoenix relies on the "Result Of protocol" http://www.boost.org/doc/libs/1_54_0/libs/utility/utility.htm#result_of but 1) at least it is possible, 2) This is less of a problem in C++11, where return types are very easy to deduce and it can be done automatically.
事实上,在C ++ 11,凤凰lambda表达式仍比功能更强大的C ++ 11
内置lambda表达式。即使在C ++ 14,其中模板是lambda表达式
实现,凤凰是还更一般地,因为它允许
一定程度的内省。 (对于此的其他事情,乔尔·德
古斯曼(凤凰城的开发商)是现在仍然是遥遥领先的他
时间)。
In fact, in C++11, Phoenix lambdas are still more powerful than C++11 built-in lambdas. Even in C++14, where template lambdas are implemented, Phoenix is still more general, because it allows a certain level of introspection. (For this an other things, Joel de Guzman (developer of Phoenix) was and still is well ahead of his time.)
这篇关于什么是使用Boost.Phoenix好处?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!