我不明白使用Boost.Phoenix的真正好处是什么。

当我将其与Boost.Spirit语法一起使用时,它真的非常有用:

double_[ boost::phoenix::push_back( boost::phoenix::ref( v ), _1 ) ]

当我将其用于lambda函数时,它也非常有用且优雅:
boost::range::for_each( my_string, if_ ( '\\' == arg1 ) [ arg1 = '/' ] );

但是该库中其他所有内容的好处是什么?该文档说:“无处不在”。我不明白这有什么好处?

最佳答案

我将向您指出Boost.Lambda和Boost.Phoenix之间的关键区别是什么:

Boost.Phoenix支持(静态)多态函子,而Boost.Lambda绑定(bind)始终是单态的。

(同时,在很多方面,这两个库可以合并,因此它们不是排他性的选择。)

让我来说明(警告:未测试代码。):

凤凰

在Phoenix中,函子可以转换为Phoenix的“惰性函数”(来自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确实是多态的(如functor is_odd_impl)。也就是说is_odd(_1)可以对任何东西起作用(有意义)。例如在is_odd(_1)(2u)==trueis_odd(_1)(2l)==true中。 is_odd可以组合成一个更复杂的表达式,而不会失去其多态行为。

Lambda尝试

在Boost.Lambda中,最接近该值的是什么,我们可以定义两个重载:
bool is_odd_overload(unsigned arg1){return arg1 % 2 == 1;}
bool is_odd_overload(long     arg1){return arg1 % 2 == 1;}

但是要创建Lambda“惰性函数”,我们将必须选择以下两个之一:
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

即使我们定义了模板版本
template<class T>
bool is_odd_template(T arg1){return arg1 % 2 == 1;}

我们将不得不绑定(bind)到模板函数的特定实例,例如
auto f3 = bind(&is_odd_template<unsigned>, _1); // not tested
f1f2f3都不是真正的多态性,因为在绑定(bind)时已做出选择。

(注1:这可能不是最好的示例,因为由于从无符号到长整数的隐式转换,事情似乎可以正常工作,但这是另一回事。)

总而言之,给定一个多态函数/函数Lambda不能绑定(bind)到该多态函数(据我所知),而Phoenix可以。 Phoenix确实依赖于“协议(protocol)结果” http://www.boost.org/doc/libs/1_54_0/libs/utility/utility.htm#result_of,但是1)至少有可能,2)在C++ 11中这不是问题,在C++ 11中,返回类型非常容易推论并且可以做到自动。

实际上,在C++ 11中,Phoenix lambda仍然比C++ 11更强大
内置的lambda。即使在C++ 14中,模板通用lambda也是
实现后,Phoenix仍然更为通用,因为它允许
一定程度的自省(introspection)。 (为此,Joel de
古兹曼(Phoenix的开发人员)过去并且现在仍然领先于他
时间。)

关于c++ - 使用Boost.Phoenix有什么好处?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5013476/

10-15 04:29