C++ 我的Phoenix lambda表达式有什么问题?

C++ 我的Phoenix lambda表达式有什么问题?,c++,boost,boost-phoenix,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 <

我希望编译以下示例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;
}
intplus(inta,intb)
{
返回a+b;
}
void main(整型argc,字符**argc)
{
auto plus_1=phx::bind(&plus,1,arg1);
自动值=phx::lambda[phx::val(plus_1)(arg1)]()(1);

std::cout我不清楚您在这里使用
lambda
想要实现什么,但是如果您只想用
1
调用
plus\u 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';
}
#包括
#包括
整数加(整数a,整数b)
{
返回a+b;
}
int main()
{
名称空间phx=boost::phoenix;
auto plus_1=phx::bind(plus,1,phx::arg_name::arg1);
标准::cout
在这一行之后,
plus_1
是一个函数对象,它接受一个
int
参数并向其中添加一个

phx::lambda[plus_1(arg1)](1);
哎哟。这行不通,因为(正如我们上面所说)
plus\u 1
是一个函数对象,它接受一个
int
参数并向其中添加一个。在这里,您试图用
arg1
调用它

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

==编辑====

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

phx::val(plus_1)(arg1)
…使用
val
创建一个空函数,该空函数返回
plus_1
一元函数。然后尝试使用
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;
}
请注意,
arg1
出现两次。所有表达式都是从内到外求值的。首先,我们将内部
arg1
绑定到
1
,然后求值内部
bind
生成
2
,然后我们尝试绑定和调用它。这是行不通的,因为
2
不可调用


使用
lambda
为内部
arg1
创建了一个作用域,因此它不会被急切地替换。但正如我所说,使用第二个
bind
,这迫使需要
lambda
,产生了一个与第一个相当的函数。因此它不必要地复杂。但它可能帮助您理解
>bind
lambda
和Phoenix示波器。

也许这可以更好地解释它

<菲尼克斯>不是魔术,它首先是C++,因此遵循C++的规则。
phx::bind
是一个返回函数对象的函数,该对象具有重载的
运算符()
,该运算符调用绑定的函数。您的第一条语句将此对象存储到
plus\u 1

考虑到所有这些,任何时候您都有表达式
加上_1(…)
,这是一个函数调用。就是这样;您说您想对该对象的类型调用重载的
操作符()
函数,并将一些值传递给该函数


不管表达式是否在<代码> [/COD]中,也不要。<代码> PHX::lambda < /C>不能使C++改变它的规则。它不能使<代码> PLUSS1(…)>代码>除了一个即时函数调用之外。也不能<代码> ARG1使<代码> PLUSS1(…)

不是立即的函数调用。

我希望我的表达式能够工作。这不是因为我在尝试添加数字,而是因为我理解为什么lamba没有像我期望的那样做。谢谢你的解释。我想更好地理解Phoenix。根据文档,我发现bind令人困惑。我不理解的是为什么你需要用一个绑定表达式来包装lambda。是什么阻止了lambda独立存在。是因为PHX表达式真的是lambda吗?再次感谢a的回答。好的,我想我明白了。基本上函数对象不是Actor,bind不返回和Actor,而是函数对象。包装函数所需的lambda使用and Actor对对象进行惰性计算。不,
bind
表达式返回Actors。Actors是函数对象。您不需要将
lambda
包装在
bind
中。您可以这样做,例如:
int value=phx::lambda[plus_1]()(1)
lambda
就像一个间接层次;对其求值一次以获得lambda的主体,然后再次求值以获得最终结果。
#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;
}
// Oops, wrong:
int value = phx::bind(phx::bind(&plus, 1, arg1), arg1)(1);