C++ spirit::qi:将继承的属性引用传递给phoenix::function

C++ spirit::qi:将继承的属性引用传递给phoenix::function,c++,boost-spirit-qi,C++,Boost Spirit Qi,下面的代码是我尝试执行的操作的简化版本。基本上,我有一个struct(玩具代码中的int_holder)和一个容器数据成员。我想插入一个对象(本例中为int)并将指向新插入对象的指针返回到父qi::rule 我通过引用将int_持有者传递给语法,以便在解析时用值填充它,因此int_持有者将是语法的继承属性。代码: #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/phoenix_core.

下面的代码是我尝试执行的操作的简化版本。基本上,我有一个struct(玩具代码中的int_holder)和一个容器数据成员。我想插入一个对象(本例中为int)并将指向新插入对象的指针返回到父qi::rule

我通过引用将int_持有者传递给语法,以便在解析时用值填充它,因此int_持有者将是语法的继承属性。代码:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <vector>

namespace qi=boost::spirit::qi;
namespace phoenix=boost::phoenix;

struct int_holder
{
    int_holder() {}
    std::vector<int> ints;
};


struct insert_impl
{
    template<class, class>
    struct result { typedef int* type; };
    int* operator() (int_holder& holder, int i) const
    {
        holder.ints.push_back (i);
        return &holder.ints.back();
    }
};

template<class Iterator>
struct my_grammar : qi::grammar<Iterator, int*(int_holder&)>
{
    my_grammar () : my_grammar::base_type (start)
          , insert (insert_impl())
    {
        using qi::_val;
        using qi::int_;
        using qi::_r1;
        using qi::_1;

        using phoenix::ref;

        start = +next(_val) [_val = _1];
        next = int_ [_val = insert(_r1, _1)];
    }
    qi::rule<Iterator, int*(int_holder&)> start, next;
    phoenix::function<insert_impl> insert;
};


int main ()
{
    using phoenix::ref;

    const char* p="1";
    int* last;
    int_holder holder;
    my_grammar<const char*> g;
    qi::parse (p, p+1, g(ref(holder)), last);
}
#包括
#包括
#包括
#包括
#包括
名称空间qi=boost::spirit::qi;
名称空间phoenix=boost::phoenix;
结构内固定器
{
int_holder(){}
std::向量整数;
};
结构插入\u impl
{
模板
结构结果{typedef int*type;};
int*运算符()
{
支架内压回(i);
return&holder.int.back();
}
};
模板
struct my_语法:qi::grammar
{
我的语法():我的语法::基本类型(开始)
,insert(insert_impl())
{
使用qi:(u val);
使用qi::int_;
使用qi:_r1;
使用气::_1;
使用phoenix::ref;
开始=+下一步(_val)[u val=_1];
next=int_[_val=insert(_r1,_1)];
}
qi::规则开始,下一步;
菲尼克斯:函数插入;
};
int main()
{
使用phoenix::ref;
常量字符*p=“1”;
int*last;
国际持有人;
我的语法;
qi::parse(p,p+1,g(ref(holder)),last);
}
代码未编译,并显示以下错误消息:

In file included from     
/opt/local/include/boost/fusion/sequence/intrinsic/detail/segmented_begin.hpp:16:0,
         from /opt/local/include/boost/fusion/sequence/intrinsic/begin.hpp:17, from
         /opt/local/include/boost/fusion/iterator/segmented_iterator.hpp:12, from
         /opt/local/include/boost/fusion/sequence/intrinsic/detail/segmented_end.hpp:11, from
         /opt/local/include/boost/fusion/sequence/intrinsic/end.hpp:17, from
         /opt/local/include/boost/fusion/sequence/intrinsic/back.hpp:11, from
         /opt/local/include/boost/fusion/sequence/intrinsic.hpp:11, from
         /opt/local/include/boost/fusion/include/intrinsic.hpp:10, from
         /opt/local/include/boost/proto/fusion.hpp:22, from
         /opt/local/include/boost/proto/core.hpp:21, from
         /opt/local/include/boost/proto/proto.hpp:12, from
         /opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19, from
         /opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14, from
         /opt/local/include/boost/spirit/home/qi/action/action.hpp:14, from
         /opt/local/include/boost/spirit/home/qi/action.hpp:14, from
         /opt/local/include/boost/spirit/home/qi.hpp:14, from
         /opt/local/include/boost/spirit/include/qi.hpp:16, from test_qi.cpp:1:
         /opt/local/include/boost/fusion/container/list/cons.hpp: In instantiation of
         'boost::fusion::cons<Car, Cdr>::cons(const boost::fusion::cons<Car2, Cdr2>&) [with Car2 =
         int*&; Cdr2 = boost::fusion::nil; Car = int_holder&; Cdr = boost::fusion::nil]':
         /opt/local/include/boost/spirit/home/support/context.hpp:117:20: required from
         'boost::spirit::context<Attributes, Locals>::context(typename Attributes::car_type, const
         Args&, Context&) [with Args =
         boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_>; Context = boost::spirit::context<boost::fusion::cons<int*&,
         boost::fusion::cons<int_holder&, boost::fusion::nil> >, boost::fusion::vector0<> >;
         Attributes = boost::fusion::cons<int*&, boost::fusion::cons<int_holder&,
         boost::fusion::nil> >; Locals = boost::fusion::vector0<>; typename Attributes::car_type =
         int*&]' /opt/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:343:67: required
         from 'bool boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::parse(Iterator&, const
         Iterator&, Context&, const Skipper&, Attribute&, const Params&) const [with Context =
         boost::spirit::context<boost::fusion::cons<int*&, boost::fusion::cons<int_holder&,
         boost::fusion::nil> >, boost::fusion::vector0<> >; Skipper = boost::spirit::unused_type;
         Attribute = int*; Params =
         boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_>; Iterator = const char*; T1 = int*(int_holder&); T2 =
         boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 =
         boost::spirit::unused_type]'
         /opt/local/include/boost/spirit/home/qi/nonterminal/detail/parameterized.hpp:48:79:
         required from 'bool boost::spirit::qi::parameterized_nonterminal<Subject,
         Params>::parse(Iterator&, const Iterator&, Context&, const Skipper&, Attribute&) const
         [with Iterator = const char*; Context = boost::spirit::context<boost::fusion::cons<int*&,
         boost::fusion::cons<int_holder&, boost::fusion::nil> >, boost::fusion::vector0<> >;
         Skipper = boost::spirit::unused_type; Attribute = int*; Subject =
         boost::spirit::qi::rule<const char*, int*(int_holder&), boost::spirit::unused_type,
         boost::spirit::unused_type, boost::spirit::unused_type>; Params =
         boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_>]' /opt/local/include/boost/spirit/home/qi/action/action.hpp:65:13:
         required from 'bool boost::spirit::qi::action<Subject, Action>::parse(Iterator&, const
         Iterator&, Context&, const Skipper&, Attribute&) const [with Iterator = const char*;
         Context = boost::spirit::context<boost::fusion::cons<int*&,
         boost::fusion::cons<int_holder&, boost::fusion::nil> >, boost::fusion::vector0<> >;
         Skipper = boost::spirit::unused_type; Attribute = boost::spirit::unused_type; Subject =
         boost::spirit::qi::parameterized_nonterminal<boost::spirit::qi::rule<const char*,
         int*(int_holder&), boost::spirit::unused_type, boost::spirit::unused_type,
         boost::spirit::unused_type>,
         boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_> >; Action =
         boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval,
         boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >
         >]' /opt/local/include/boost/spirit/home/qi/detail/fail_function.hpp:38:72: required from
         'bool boost::spirit::qi::detail::fail_function<Iterator, Context,
         Skipper>::operator()(const Component&, Attribute&) const [with Component =
         boost::spirit::qi::action<boost::spirit::qi::parameterized_nonterminal<boost::spirit::qi::rule<const
         char*, int*(int_holder&), boost::spirit::unused_type, boost::spirit::unused_type,
         boost::spirit::unused_type>,
         boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_> >,
         boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval,
         boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >
         > >; Attribute = boost::spirit::unused_type; Iterator = const char*; Context =
         boost::spirit::context<boost::fusion::cons<int*&, boost::fusion::cons<int_holder&,
         boost::fusion::nil> >, boost::fusion::vector0<> >; Skipper = boost::spirit::unused_type]'
         /opt/local/include/boost/spirit/home/qi/detail/pass_container.hpp:263:38: [ skipping 10
         instantiation contexts ] /opt/local/include/boost/function/function_template.hpp:1042:16:
         required from 'boost::function<R(T0, T1, T2, T3)>::function(Functor, typename
         boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value,
         int>::type) [with Functor =
         boost::spirit::qi::detail::parser_binder<boost::spirit::qi::plus<boost::spirit::qi::action<boost::spirit::qi::parameterized_nonterminal<boost::spirit::qi::rule<const
         char*, int*(int_holder&), boost::spirit::unused_type, boost::spirit::unused_type,
         boost::spirit::unused_type>,
         boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_> >,
         boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval,
         boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >
         > > >, mpl_::bool_<false> >; R = bool; T0 = const char*&; T1 = const char* const&; T2 =
         boost::spirit::context<boost::fusion::cons<int*&, boost::fusion::cons<int_holder&,
         boost::fusion::nil> >, boost::fusion::vector0<> >&; T3 = const
         boost::spirit::unused_type&; typename
         boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value,
         int>::type = int]' /opt/local/include/boost/function/function_template.hpp:1083:5:
         required from 'typename
         boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value,
         boost::function<R(T0, T1, T2, T3)>&>::type boost::function<R(T0, T1, T2,
         T3)>::operator=(Functor) [with Functor =
         boost::spirit::qi::detail::parser_binder<boost::spirit::qi::plus<boost::spirit::qi::action<boost::spirit::qi::parameterized_nonterminal<boost::spirit::qi::rule<const
         char*, int*(int_holder&), boost::spirit::unused_type, boost::spirit::unused_type,
         boost::spirit::unused_type>,
         boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_> >,
         boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval,
         boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >
         > > >, mpl_::bool_<false> >; R = bool; T0 = const char*&; T1 = const char* const&; T2 =
         boost::spirit::context<boost::fusion::cons<int*&, boost::fusion::cons<int_holder&,
         boost::fusion::nil> >, boost::fusion::vector0<> >&; T3 = const
         boost::spirit::unused_type&; typename
         boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value,
         boost::function<R(T0, T1, T2, T3)>&>::type = boost::function<bool(const char*&, const
         char* const&, boost::spirit::context<boost::fusion::cons<int*&,
         boost::fusion::cons<int_holder&, boost::fusion::nil> >, boost::fusion::vector0<> >&,
         const boost::spirit::unused_type&)>&]'
         /opt/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:182:13: required from
         'static void boost::spirit::qi::rule<Iterator, T1, T2, T3,
         T4>::define(boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&, const Expr&, mpl_::true_)
         [with Auto = mpl_::bool_<false>; Expr =
         boost::proto::exprns_::expr<boost::proto::tagns_::tag::unary_plus,
         boost::proto::argsns_::list1<const
         boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript,
         boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,
         boost::proto::argsns_::term<boost::spirit::qi::parameterized_nonterminal<boost::spirit::qi::rule<const
         char*, int*(int_holder&), boost::spirit::unused_type, boost::spirit::unused_type,
         boost::spirit::unused_type>,
         boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_> > >, 0l>&,
         boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,
         boost::proto::argsns_::term<const
         boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval,
         boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >
         >&>, 0l> >, 2l>&>, 1l>; Iterator = const char*; T1 = int*(int_holder&); T2 =
         boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 =
         boost::spirit::unused_type; boost::spirit::qi::rule<Iterator, T1, T2, T3, T4> =
         boost::spirit::qi::rule<const char*, int*(int_holder&), boost::spirit::unused_type,
         boost::spirit::unused_type, boost::spirit::unused_type>; mpl_::true_ =
         mpl_::bool_<true>]' /opt/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:220:13:
         required from 'boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&
         boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::operator=(const Expr&) [with Expr =
         boost::proto::exprns_::expr<boost::proto::tagns_::tag::unary_plus,
         boost::proto::argsns_::list1<const
         boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript,
         boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,
         boost::proto::argsns_::term<boost::spirit::qi::parameterized_nonterminal<boost::spirit::qi::rule<const
         char*, int*(int_holder&), boost::spirit::unused_type, boost::spirit::unused_type,
         boost::spirit::unused_type>,
         boost::fusion::vector<boost::phoenix::actor<boost::spirit::attribute<0> >,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_> > >, 0l>&,
         boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,
         boost::proto::argsns_::term<const
         boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval,
         boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
         boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >
         >&>, 0l> >, 2l>&>, 1l>; Iterator = const char*; T1 = int*(int_holder&); T2 =
         boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 =
         boost::spirit::unused_type; boost::spirit::qi::rule<Iterator, T1, T2, T3, T4> =
         boost::spirit::qi::rule<const char*, int*(int_holder&), boost::spirit::unused_type,
         boost::spirit::unused_type, boost::spirit::unused_type>]' test_qi.cpp:41:3: required from
         'my_grammar<Iterator>::my_grammar() [with Iterator = const char*]' test_qi.cpp:57:26:
         required from here /opt/local/include/boost/fusion/container/list/cons.hpp:83:40: error:
         invalid initialization of reference of type 'boost::fusion::cons<int_holder&,
         boost::fusion::nil>::car_type {aka int_holder&}' from expression of type 'int*'
包含在从
/opt/local/include/boost/fusion/sequence/intrinsive/detail/segmented_begin.hpp:16:0,
from/opt/local/include/boost/fusion/sequence/intrinsive/begin.hpp:17,from
/opt/local/include/boost/fusion/iterator/segmented_iterator.hpp:12,from
/opt/local/include/boost/fusion/sequence/intrinsive/detail/segmented_end.hpp:11,from
/opt/local/include/boost/fusion/sequence/intrinsive/end.hpp:17,from
/opt/local/include/boost/fusion/sequence/intrinsive/back.hpp:11,from
/opt/local/include/boost/fusion/sequence/infrance.hpp:11,from
/opt/local/include/boost/fusion/include/intrinsive.hpp:10,来自
/opt/local/include/boost/proto/fusion.hpp:22,来自
/opt/local/include/boost/proto/core.hpp:21,来自
/opt/local/include/boost/proto/proto.hpp:12,来自
/opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19,from
/opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14,from
/opt/local/include/boost/spirit/home/qi/action/action.hpp:14,from
/opt/local/include/boost/spirit/home/qi/action.hpp:14,from
/opt/local/include/boost/spirit/home/qi.hpp:14,from
/opt/local/include/boost/spirit/include/qi.hpp:16,来自测试_qi.cpp:1:
/opt/local/include/boost/fusion/container/list/cons.hpp:在
'boost::fusion::cons::cons(const boost::fusion::cons&)[与Car2一起=
int*&;Cdr2=boost::fusion::nil;Car=int_holder&;Cdr=boost::fusion::nil]:
/opt/local/include/boost/spirit/home/support/context。hpp:117:20:需要从
'boost::spirit::context::context(typename属性::car_类型,const
Args&,Context&[带Args=
boost::fusion::vector;Context=boost::spirit::Context;
Attributes=boost::fusion::cons;Locals=boost::fusion::vector0;typename属性::car\u类型=
int*&]'/opt/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:343:67:必需
来自'bool boost::spirit::qi::rule::parse(迭代器&,常量
迭代器&,上下文&,常量跳过器&,属性&,常量参数&)常量[带上下文=
boost::spirit::context;Skipper=boost::spirit::unused\u type;
属性=int*;参数=
boost::fusion::vector;迭代器=const char*;T1=int*(int_holder&);T2=
boost::spirit::未使用的类型;T3=boost::spirit::未使用的类型;T4=
boost::spirit::未使用的类型]'
/opt/local/include/boost/spirit/home/qi/nonterminal/detail/parameterized.hpp:48:79:
“bool boost::spirit::qi::parameterized_nonterminal::parse(迭代器&,常量迭代器&,上下文&,常量跳过器&,属性&)”常量中需要
[with Iterator=const char*;Context=boost::spirit::Context;
Skipper=boost::spirit::unused_type;Attribute=int*;Subject=
boost::spirit::qi::rule;Params=
boost::fusion::vector]'/opt/local/include/boost/spirit/home/qi/action/action.hpp:65:13:
“bool boost::spirit::qi::action::parse(迭代器&,常量)中需要
迭代器&,上下文&,常量跳过器&,属性&)常量[带迭代器=常量字符*;
Context=boost::spirit::Context;
Skipper=boost::spirit::unused\u type;Attribute=boost::spirit::unused\u type;Subject=
boost::spirit::qi::参数化的_非终结符;操作=
boost::phoenix::actor]'/opt/local/include/boost/spirit/home/qi/detail/fail_函数。hpp:38:72:需要从
'bool boost::spirit::qi::detail::fail_函数::operator()(常量组件&,属性&)常量[带组件=
boost::spirit::qi::action;Attribute=boost::spirit::unused_type;Iterator=const char*;Context=
boost::spirit::context;Skipper=boost::spirit::unused\u type]'
/opt/local/include/boost/spirit/home/qi/detail/pass_container.hpp:263:38:[跳过10
实例化上下文]/opt/local/include/boost/function/function_template.hpp:1042:16:
boost::function::function(Functor,typename)中需要
boost::启用_if_c::type)[带函子=
boost::spirit::qi::detail::parser_binder;R=bool;T0=const char*&;T1=const char*const&;T2=
boost::spirit::context&;T3=const
boost::spirit::未使用的类型&;类型名
boost::启用(如果_c::type=int]'/opt/local/include/boos
start = +next(_val) [_val = _1];
start = +next(_r1) [_val = _1];