[英]What is wrong with my Phoenix lambda expression?
I would expect the following example Boost Phoenix expression to compile. 我希望下面的示例Boost Phoenix表达式可以编译。
What am I missing? 我想念什么?
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;
}
auto plus_1 = phx::bind(&plus,1,arg1);
After this line, plus_1
is a function object that takes one int
argument and adds one to it. 在此行之后,
plus_1
是一个函数对象,该对象接受一个int
参数并将其添加一个参数。
phx::lambda[plus_1(arg1)](1);
Whoops. 哎呀 This isn't going to work because (as we said above)
plus_1
is a function object that takes one int
argument and adds one to it. 这是行不通的,因为(如上所述)
plus_1
是一个函数对象,它接受一个int
参数并将其添加一个。 Here, you're trying to invoke it with arg1
. 在这里,您尝试使用
arg1
调用它。
It isn't obvious from your code what you expect it to do. 从您的代码中看不出您期望它做什么。 Can you clarify?
你能澄清一下吗?
====EDIT==== ====编辑====
I see you've edited the code in your question. 我们看到您已修改问题中的代码。 Your code is still wrong but for a different reason now.
您的代码仍然是错误的,但是现在是由于其他原因。 This:
这个:
phx::val(plus_1)(arg1)
... uses val
to create a nullary function that returns the plus_1
unary function. ...使用
val
创建一个空函数,该函数返回plus_1
一元函数。 You then try to invoke the nullary function with arg1
. 然后,您尝试使用
arg1
调用无效函数。 Boom. 繁荣。
Here is code that executes and does (what I believe) you intend: 这是执行和执行(我相信)您打算的代码:
#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;
}
The first bind
takes the binary plus
and turns it into a unary function with the first argument bound to 1
. 第一个
bind
采用二进制plus
并将其转换为一元函数,且第一个参数绑定为1
。 The second bind
creates a new unary function that is equivalent to the first , but it does so by safely wrapping the first function using lambda
. 第二个
bind
创建了一个新的一元函数,该函数bind
一个bind
等效 ,但是它是通过使用lambda
安全地包装第一个函数来实现的。 Why is that necessary? 为什么有必要? Consider the code below, which is equivalent, but without the
lambda
: 考虑下面的代码,这是等效的,但没有
lambda
:
// Oops, wrong:
int value = phx::bind(phx::bind(&plus, 1, arg1), arg1)(1);
Notice that arg1
appears twice. 注意
arg1
出现了两次。 All expressions get evaluated from the inside out. 从内到外对所有表达式求值。 First, we'll bind the inner
arg1
to 1
, then evaluate the inner bind
yielding 2
, which we then try to bind and invoke. 首先,我们将内部
arg1
绑定到1
,然后评估内部bind
产生2
,然后尝试进行绑定和调用。 That's not going to work because 2
isn't callable. 那是行不通的,因为
2
是不可调用的。
The use of lambda
creates a scope for the inner arg1
so it isn't eagerly substituted. 使用
lambda
会为内部arg1
创建一个范围,因此不会急切地替换它。 But like I said, the use of the second bind
, which forces the need for lambda
, yields a function that is equivalent to the first. 但是就像我说的那样,使用第二个
bind
强制需要lambda
,它产生的功能与第一个相同。 So it's needlessly complicated. 因此,它不必要地复杂。 But maybe it helped you understand about
bind
, lambda
and Phoenix scopes. 但是也许它可以帮助您了解
bind
, lambda
和Phoenix范围。
It's not clear to me what you're trying to accomplish by using lambda
here, but if you just want to call plus_1
with 1
(resulting in 2
), it's much simpler than your attempt: 我不清楚您要在此处使用
lambda
试图完成什么,但是如果您只想用1
调用plus_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';
}
If this isn't what you're trying to accomplish, then you need to describe what you actually want. 如果这不是您要实现的目标,则需要描述您实际想要的目标。 :-]
:-]
Perhaps this can explain it better. 也许这可以更好地解释它。
Phoenix is not magic ; 凤凰不是魔术 ; it is first and foremost C++.
它是最重要的C ++。 It therefore follows the rules of C++.
因此,它遵循C ++的规则 。
phx::bind
is a function that returns a function object, an object which has an overloaded operator()
that calls the function that was bound. phx::bind
是一个返回函数对象的函数,该对象具有重载的operator()
,该operator()
调用绑定的函数。 Your first statement stores this object into plus_1
. 您的第一条语句将该对象存储到
plus_1
。
Given all of this, anytime you have the expression plus_1(...)
, this is a function call . 鉴于这一切, 任何时候你有表达
plus_1(...)
这是一个函数调用 。 That's what it is; 就是这样; you are saying that you want to call the overloaded
operator()
function on the type of that object, and that you are going to pass some values to that function. 您是说要对该对象的类型调用重载的
operator()
函数,并且要向该函数传递一些值。
It doesn't matter whether that expression is in the middle of a []
or not. 该表达式是否位于
[]
中间并不重要。 phx::lambda
cannot make C++ change its rules. phx::lambda
无法使C ++更改其规则。 It can't make plus_1(...)
anything other than an immediate function call. 它不能使
plus_1(...)
不是立即函数调用其他任何东西。 Nor can arg1
make plus_1(...)
not an immediate function call. arg1
也不能进行plus_1(...)
不是立即函数调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.