C++ Phoenix中的成员函数调整问题
我在精神上一直使用C++ Phoenix中的成员函数调整问题,c++,boost,boost-phoenix,C++,Boost,Boost Phoenix,我在精神上一直使用BOOST\u PHOENIX\u ADAPT\u功能。出于同样的原因,我希望能够调整成员功能。但是,如果执行以下操作,则会出现编译错误: struct A { int foo(int i) { return 5*i; }}; BOOST_PHOENIX_ADAPT_FUNCTION(int, AFoo, &A::foo, 2) 是否有一种简单的方法来调整成员函数?请注意,我不能只将绑定表达式存储在auto中,因为我在VC2008上。为什么它不只是像在bind和函数
BOOST\u PHOENIX\u ADAPT\u功能。出于同样的原因,我希望能够调整成员功能。但是,如果执行以下操作,则会出现编译错误:
struct A { int foo(int i) { return 5*i; }};
BOOST_PHOENIX_ADAPT_FUNCTION(int, AFoo, &A::foo, 2)
是否有一种简单的方法来调整成员函数?请注意,我不能只将绑定表达式存储在auto
中,因为我在VC2008上。为什么它不只是像在bind
和函数中那样工作
谢谢
迈克从最简单的开始:
为什么它不只是像在绑定和函数中那样工作
因为宏是为函数而不是成员函数设计的。指向成员函数的指针与函数指针大不相同,所以这就是路的尽头
在您的示例中,A::foo
实际上不需要是实例方法(非静态成员函数),因此只需添加static
(和隐式参数)即可:
struct A {
static int foo(int i) {
return 5*i;
}
};
BOOST_PHOENIX_ADAPT_FUNCTION(int, AFoo, A::foo, 1)
不过,让我们假设您确实希望使用非静态成员函数。因此,让我们为a
类型添加一点状态:
struct A {
A(int f) : f_(f) {}
int foo(int i) { return f_*i; }
private:
int f_;
};
Phoenix提供以下方法来创建调用成员函数的惰性参与者:
使用->*
运算符。这导致语法有点模糊:
A instance(9);
int direct = (arg1->*&A::foo)(arg2)
(&instance, 7); // direct == 63
或者,您可以使用bind
表达式(注意:boost::phoenix::bind
此处!),这可能正是您所需要的:
int with_bind = bind(&A::foo, arg1, arg2)
(&instance, 7);
当然,现在您可能希望将惰性函子指定给一个变量。在这方面,我只能推荐BOOST\u AUTO
:
BOOST_AUTO(afoo, (arg1->*&A::foo)(arg2));
return afoo(&instance, 2);
这就像一个符咒
完整的C++03示例
查看它
struct A {
A(int f) : f_(f) {}
int foo(int i) {
return f_*i;
}
private:
int f_;
};
#include <boost/phoenix.hpp>
#include <boost/phoenix/function.hpp>
#include <cassert>
int main() {
using namespace boost::phoenix;
using namespace boost::phoenix::arg_names;
A instance(9);
int direct = (arg1->*&A::foo)(arg2)
(&instance, 7);
int with_bind = bind(&A::foo, arg1, arg2)
(&instance, 7);
assert(direct == with_bind);
BOOST_AUTO(afoo, (arg1->*&A::foo)(arg2));
return afoo(&instance, 2);
}
结构A{
A(intf):f_f(f){}
int foo(int i){
返回f_*i;
}
私人:
int f_2;;
};
#包括
#包括
#包括
int main(){
使用名称空间boost::phoenix;
使用名称空间boost::phoenix::arg_名称;
实例(9);
int direct=(arg1->*&A::foo)(arg2)
(例7),;
int与_bind=bind(&A::foo,arg1,arg2)
(例7),;
断言(direct==与_绑定);
BOOST_AUTO(afoo,(arg1->*&A::foo)(arg2));
返回afoo(&实例,2);
}
BOOST\u PHOENIX\u ADAPT\u函数(RETURN,LAZY\u NAME,FUNC,N)
非常简单。它只是创建了一个带有模板化的操作符()
的函子,该函子返回RETURN
,并具有N
模板参数。在其主体中,它只调用FUNC(参数…
)。但是&A::foo
不能直接调用,因此会发生错误。您可以使用:
BOOST_PHOENIX_ADAPT_FUNCTION(int,AFoo,boost::mem_fn(&A::foo),2)
#包括
#包括
#包括
#包括
结构A{
A(intf):f_f(f){}
int foo(int i){
返回f_*i;
}
私人:
int f_2;;
};
BOOST_PHOENIX_ADAPT_函数(int、AFoo、BOOST::mem_fn(&A::foo),2)
int main(){
使用名称空间boost::phoenix;
使用名称空间boost::phoenix::arg_名称;
实例(5);
std::cout谢谢你的回答。不幸的是,这正是我所担心的。在我的VS2008程序中,唯一对我有效的是绑定解决方案,这是我一直在使用的解决方案,并且希望有更好的解决方案(由于嵌套模板,有一些不可靠的上下文).哦,好吧,至少知道是好的。我知道这个答案来得太晚了,但它可能会对未来的访客有所帮助。
#include <iostream>
#include <boost/phoenix.hpp>
#include <boost/phoenix/function.hpp>
#include <boost/mem_fn.hpp>
struct A {
A(int f) : f_(f) {}
int foo(int i) {
return f_*i;
}
private:
int f_;
};
BOOST_PHOENIX_ADAPT_FUNCTION(int,AFoo,boost::mem_fn(&A::foo),2)
int main() {
using namespace boost::phoenix;
using namespace boost::phoenix::arg_names;
A instance(5);
std::cout << AFoo(arg1,arg2)(&instance, 2) << std::endl;
}