0

我希望以下示例 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;
}
4

3 回答 3

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

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

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

哎呀。这是行不通的,因为(如上所述)plus_1是一个函数对象,它接受一个int参数并向其添加一个参数。在这里,您尝试使用arg1.

从您的代码中看不出您期望它做什么。你能澄清一下吗?

====编辑====

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

phx::val(plus_1)(arg1)

... 用于val创建一个返回plus_1一元函数的空函数。然后,您尝试使用 调用 nullary 函数arg1。繁荣。

这是执行和执行(我相信)您想要的代码:

#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的新一元函数,但它是通过使用 安全地包装第一个函数来实现的。为什么这是必要的?考虑下面的代码,它是等效的,但没有:lambdalambda

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

请注意,它arg1出现了两次。所有表达式都是从内到外进行评估的。首先,我们将内部绑定arg11,然后评估内部bindyielding 2,然后我们尝试绑定并调用它。那是行不通的,因为2它是不可调用的。

的使用为lambda内部创建了一个范围,arg1因此它不会被急切地替换。但是就像我说的那样,使用第二个bind,它强制需要 for lambda,产生一个与第一个等效的函数。所以它是不必要的复杂。但也许它可以帮助您了解bind,lambda和 Phoenix 范围。

于 2012-09-29T02:01:19.410 回答
2

我不清楚你想通过lambda在这里使用来完成什么,但如果你只是想plus_11(导致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';
}

在线演示

如果这不是你想要完成的,那么你需要描述你真正想要的。:-]

于 2012-09-28T21:19:32.113 回答
1

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

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

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

考虑到这一切,只要你有表达式plus_1(...),这就是一个函数调用。就是这样;你是说你想在operator()那个对象的类型上调用重载函数,并且你要把一些值传递给那个函数。

该表达式是否在 a 的中间[]并不重要。phx::lambda不能让 C++ 改变它的规则。除了立即函数调用之外,不能进行plus_1(...)任何操作。也不能立即调用函数。arg1plus_1(...)

于 2012-10-01T16:39:55.757 回答