我一直在精神中使用BOOST_PHOENIX_ADAPT_FUNCTION
。我希望能够出于同样的原因调整成员函数。但是,如果我这样做,我会遇到编译错误:
struct A { int foo(int i) { return 5*i; }};
BOOST_PHOENIX_ADAPT_FUNCTION(int, AFoo, &A::foo, 2)
是否有一种简单的方法来适应成员函数?请注意,我不能只在auto
中存储绑定表达式,因为我在VC2008上。为什么它不像bind
和function
那样工作?
谢谢,
麦克
答案 0 :(得分:1)
BOOST_PHOENIX_ADAPT_FUNCTION(RETURN,LAZY_NAME,FUNC,N)
非常简单。它只是创建一个带有模板operator()
的仿函数,它返回RETURN
并具有N
模板参数。在它的主体中,它只是调用FUNC(PARAMETERS...)
。但是&A::foo
不能直接调用,因此会发生错误。您可以使用:
BOOST_PHOENIX_ADAPT_FUNCTION(int,AFoo,boost::mem_fn(&A::foo),2)
http://flask-marshmallow.readthedocs.org/en/latest/
#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;
}
答案 1 :(得分:0)
从最简单的开始:
为什么它不仅仅在bind和function中起作用?
因为宏是为函数而设计的,而不是成员函数。指向成员函数的指针与函数指针非常不同,所以这就是结束。
在您的示例中,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提供了以下方法来创建调用成员函数的惰性actor:
使用->*
运算符。这会导致语法略显模糊:
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_AUTO
:
BOOST_AUTO(afoo, (arg1->*&A::foo)(arg2));
return afoo(&instance, 2);
这就像魅力一样。
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);
}