凤凰lambda和论证解除引用

时间:2011-09-22 05:50:43

标签: c++ boost-phoenix

有人可以告诉我如何使用boost :: phoenix lambda实现以下的等价物吗? 我知道我可以通过许多其他方式实现它,但我正在尝试学习Phoenix lambda表达式,到目前为止,我在这个例子中的所有尝试都失败了。

我想要做的是使用std :: remove_if迭代我的weak_ptrs集并删除过期的。

所以代码看起来像是:

typedef std::set<weak_ptr<Xyz>> XyzWptrSetType;
...
XyzWptrSetType   xyzWptrSet;
...
XyzWptrSetType::iterator it =
    std::remove_if(xyzWptrSet.begin(), xyzWptrSet.end(),
                   (boost::phoenix::arg_names::_1->expied()));  
// the lambda part DOESN'T compile in previous line
std::erase(it, xyzWptrSet.end());

我发现的大多数lambda示例都非常简单,并且不处理在lambda参数对象上调用成员函数,尤其是当有多个级别的间接时。即期望_1代表集合的迭代器,通过解除引用“ - &gt;”返回我要调用的value_type(是weak_ptr)。但是因为_1实际上不是直接是迭代器而是“凤凰::演员”,所以我的解引用不会编译。

提前感谢所有创意投入。

加布

2 个答案:

答案 0 :(得分:5)

Boost.Phoenix和之前的Boost.Lambda,在某些任务上表现出色,但在其他任务中表现不佳。其中一个没有真正起作用的是与名称直接调用函数有关。

可以快速轻松地为重载运算符创建Boost.Phoenix lambdas。但是如果你需要一个函数名,那么你必须使用丑陋的语法:

boost::phoenix::bind(&boost::weak_ptr::expired, boost::phoenix::arg_names::_1)

这就是你的lambda的样子。您可以使用一些using指令来剪切名称空间,但这最终会是它的样子。它与此时使用boost::bind没有什么不同:

boost::bind(&boost::weak_ptr::expired, _1)

Boost.Phoenix和它之前的Boost.Lambda最适合用于使用重载运算符或显式定义的Phoenix动作对象的lambda表达式。如果你只有一个普通的旧函数或成员函数,你必须绑定它来调用它。所以你也可以使用boost::bind

答案 1 :(得分:2)

Boost phoenix(和boost lambda)不支持 - &gt;运营商。您可以使用“指向成员的指针”运算符( - &gt; *)作为合理的替代方法。

我发现在使用lambda表达式的行之前将成员指针定义为单独的变量很有用:

bool (weak_ptr<Xyz>::*expired)()const = &weak_ptr<Xyz>::expired ;
XyzWptrSetType::iterator it =
    std::remove_if(xyzWptrSet.begin(), xyzWptrSet.end(), (&_1->*expired)() );

正如其他人所说,对于像你这样的情况,也值得考虑使用bind()。