我的凤凰lambda表达有什么问题?

时间:2012-09-28 21:05:55

标签: c++ boost boost-phoenix

我希望以下示例Boost Phoenix表达式能够编译。

我错过了什么?

int plus(int a,int b)
{
    return a+b;
}

void main(int argc,char** argc)
{
    auto plus_1 = phx::bind(&plus,1,arg1);
    auto value  = phx::lambda[phx::val(plus_1)(arg1)]()(1);
    std::cout << value << std::endl;
}

3 个答案:

答案 0 :(得分:4)

auto plus_1 = phx::bind(&plus,1,arg1);

在此行之后,plus_1是一个函数对象,它接受一个int参数并向其添加一个。

phx::lambda[plus_1(arg1)](1);

糟糕。这是行不通的,因为(正如我们上面所说)plus_1是一个函数对象,它接受一个int参数并向其中添加一个参数。在这里,您尝试使用arg1调用它。

从您的代码中可以看出您的期望是什么。你能说清楚吗?

<强> ==== EDIT ====

我看到你已经在你的问题中编辑了代码。您的代码仍然是错误的,但现在出于不同的原因。这样:

phx::val(plus_1)(arg1)

...使用val创建一个返回plus_1一元函数的nullary函数。然后尝试使用arg1调用nullary函数。吊杆。

以下代码执行并执行(我相信)您打算:

#include <iostream>
#include <boost/phoenix/phoenix.hpp>
namespace phx = boost::phoenix;
using phx::arg_names::arg1;

int plus(int a,int b)
{
    return a+b;
}

int main()
{
    auto plus_1 = phx::bind(&plus, 1, arg1);
    int value = phx::bind(phx::lambda[plus_1], arg1)(1);
    std::cout << value << std::endl;
}

第一个bind接受二进制plus并将其转换为一元函数,第一个参数绑定到1。第二个bind创建了一个新的一元函数,它等同于第一个,但它是通过使用lambda安全地包装第一个函数来实现的。为什么这有必要?考虑下面的代码,它是等效的,但没有lambda

// Oops, wrong:
int value = phx::bind(phx::bind(&plus, 1, arg1), arg1)(1);

请注意arg1出现两次。所有表达式都由内而外进行评估。首先,我们将内部arg1绑定到1,然后评估内部bind产生2,然后我们尝试绑定和调用它们。这不起作用,因为2不可调用。

使用lambda会为内部arg1创建一个范围,因此不会急切地替换它。但就像我说的那样,使用强制需要bind的第二个lambda会产生一个与第一个相同的函数。所以这是不必要的复杂。但也许这有助于您了解bindlambda和凤凰范围。

答案 1 :(得分:2)

我不清楚您在此处使用lambda想要实现的目标,但如果您只想使用plus_1致电1(导致2 ),它比你的尝试简单得多:

#include <iostream>
#include <boost/phoenix.hpp>

int plus(int a, int b)
{
    return a + b;
}

int main()
{
    namespace phx = boost::phoenix;

    auto plus_1 = phx::bind(plus, 1, phx::arg_names::arg1);
    std::cout << plus_1(1) << '\n';
}

Online demo

如果不是您要完成的任务,那么您需要描述您真正想要的内容。 : - ]

答案 2 :(得分:1)

也许这可以更好地解释它。

凤凰不是魔法;它首先是C ++。因此它遵循C ++的规则

phx::bind是一个函数,它返回一个函数对象,一个具有重载operator()的对象,它调用绑定的函数。您的第一个语句将此对象存储到plus_1

鉴于所有这一切, 随时 您有表达式plus_1(...),这是一个函数调用。就是这样;你是说你要在该对象的类型上调用重载的operator()函数,并且你要将一些值传递给该函数。

表达式是否在[]的中间并不重要。 phx::lambda无法使C ++改变其规则。它不能使plus_1(...)任何其他而不是立即函数调用。 arg1也不能使plus_1(...)成为即时函数调用。