C++ 如何从spirit语义规则绑定/调用fusion::vector中存储的boost::函数?

C++ 如何从spirit语义规则绑定/调用fusion::vector中存储的boost::函数?,c++,boost,boost-spirit,boost-fusion,C++,Boost,Boost Spirit,Boost Fusion,我试图通过qi::symbols将一些关键字处理程序(方法)映射为boost::function类型的值。所以,若找到关键字,我想调用方法。但我无法从该映射绑定方法。编译器失败,phoenix::bind上出现大量错误。我做错了什么 部分代码如下: template <typename Iterator> struct Grammar : qi::grammar<Iterator, AST::FunctionCall(), ascii::space_type> {

我试图通过qi::symbols将一些关键字处理程序(方法)映射为boost::function类型的值。所以,若找到关键字,我想调用方法。但我无法从该映射绑定方法。编译器失败,phoenix::bind上出现大量错误。我做错了什么

部分代码如下:

template <typename Iterator>
struct Grammar : qi::grammar<Iterator, AST::FunctionCall(), ascii::space_type>
{
    Grammar():
        Grammar::base_type(query),
    {
        ...
        operand =
          predicate [phoenix::bind(phoenix::at_c<0>(qi::_1), this, phoenix::at_c<1>(qi::_1))]; // **Compiler fails here**
        ...

        predicate = 
            (pred_tbl > '(')
         > -(primary_expr % ',')
         > ')';
        ... 

        pred_tbl.add
            ("composing",    &RQL::composing)
        );
    }

    qi::rule<Iterator, fusion::vector<Predicate, PredicateArgList>(), ascii::space_type>   predicate;

    typedef std::vector<AST::Value> PredicateArgList;
    typedef boost::function<void (Grammar*, const PredicateArgList& args)> Predicate;   
    qi::symbols<char, Predicate> pred_tbl;

    void composing(const PredicateArgList& args);
};
模板
结构语法:qi::Grammar
{
语法():
语法::基本类型(查询),
{
...
操作数=
谓词[phoenix::bind(phoenix::at_c(qi::_1),this,phoenix::at_c(qi:_1))];//**编译器在此失败**
...
谓词=
(pred_tbl>"()
>-(主表达式%,)
> ')';
... 
预加
(“组合”,&RQL::组合)
);
}
规则谓词;
typedef std::向量谓词glist;
typedef boost::函数谓词;
qi::符号pred_tbl;
无效组合(常量谓词glist和args);
};
编译器错误:

error C2903: 'result' : symbol is neither a class template nor a function template  c:\work\include\boost-1_41\boost\spirit\home\phoenix\core\detail\function_eval.hpp  115 
error C2039: 'result' : is not a member of 'boost::function<Signature>' c:\work\include\boost-1_41\boost\spirit\home\phoenix\core\detail\function_eval.hpp  115 
error C2059: syntax error : '<' c:\work\include\boost-1_41\boost\spirit\home\phoenix\core\detail\function_eval.hpp  115 
error C2238: unexpected token(s) preceding ';'  c:\work\include\boost-1_41\boost\spirit\home\phoenix\core\detail\function_eval.hpp  116 
error C2065: 'function_apply' : undeclared identifier   c:\work\include\boost-1_41\boost\spirit\home\phoenix\core\detail\function_eval.hpp  124 
error C2955: 'boost::mpl::eval_if' : use of class template requires template argument list  c:\work\include\boost-1_41\boost\spirit\home\phoenix\core\detail\function_eval.hpp  125 
error C2146: syntax error : missing ';' before identifier 'type'    c:\work\include\boost-1_41\boost\spirit\home\phoenix\core\detail\function_eval.hpp  126 
error C3254: 'boost::phoenix::detail::function_eval<2>::result<Env,F,A0,A1>' : class contains explicit override 'type' but does not derive from an interface that contains the function declaration c:\work\include\boost-1_41\boost\spirit\home\phoenix\core\detail\function_eval.hpp  126 
error C2838: 'type' : illegal qualified name in member declaration  c:\work\include\boost-1_41\boost\spirit\home\phoenix\core\detail\function_eval.hpp  126 
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int   c:\work\include\boost-1_41\boost\spirit\home\phoenix\core\detail\function_eval.hpp  126 
error C2602: 'boost::phoenix::detail::function_eval<2>::result<Env,F,A0,A1>::type' is not a member of a base class of 'boost::phoenix::detail::function_eval<2>::result<Env,F,A0,A1>'   c:\work\include\boost-1_41\boost\spirit\home\phoenix\core\detail\function_eval.hpp  126 
error C2868: 'boost::phoenix::detail::function_eval<2>::result<Env,F,A0,A1>::type' : illegal syntax for using-declaration; expected qualified-name  c:\work\include\boost-1_41\boost\spirit\home\phoenix\core\detail\function_eval.hpp  126 
错误C2903:“结果”:符号既不是类模板也不是函数模板c:\work\include\boost-1\u 41\boost\spirit\home\phoenix\core\detail\function\u eval.hpp 115
错误C2039:“结果”:不是“boost::function”c:\work\include\boost-1\u 41\boost\spirit\home\phoenix\core\detail\function\u eval.hpp 115的成员

错误C2059:语法错误:'我想丢失的链接可能是

#define BOOST_SPIRIT_USE_PHOENIX_V3

它打印

Hello world from 'Grammar::composing(PredicateArgList const&)' args:3
正如所料

UPDATEPS.我可能更喜欢这样编写绑定调用:

Grammar(): Grammar::base_type(predicate)
{
    using phx::bind;
    using namespace qi;

    as<PredicateArgList> coerce;

    predicate = 
        (pred_tbl > '('
                  > coerce [ -(primary_expr % ',') ]
                  > ')') 
        [ phx::bind(_1, this, _2)]
        ;

    // ...

我找到了解决此问题的方法:

1。将复杂谓词[phoenix::bind替换为:
操作数=[phoenix::bind(&RQL::dispatchPredicate,this,qi::_1)]…void dispatchPredicate(const fusion::vector&v){fusion::at_c(v)(this,fusion::at_c(v));}

我花了很长时间才从你破碎的样本中创造出令人满意的东西。你为什么不下次再做一次呢?正如我的回答所示,这对你来说不会有太多的工作。感谢你的大力帮助!很遗憾,我不得不使用boost 1.41,而这个版本没有phoenix v3支持(没有BOOST_SPIRIT_USE_PHOENIX_V3宏)我在我对原始post.Mmm的第一次评论中描述过,我使用了w/a和dispatcher函数。与自该版本以来修复的其他bug相比,缺少PHOENIX V3是一个小问题。谁/什么强迫你使用该版本?你意识到BOOST SPIRIT只是标题,对吗?我想说,马上看。(另外,我必须修复1_41_0 tst.hpp中的一个bug,以便首先编译
qi::symbols
——eek!)
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/function.hpp>
#include <boost/phoenix/fusion.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/qi.hpp>

namespace qi     = boost::spirit::qi;
namespace fusion = boost::fusion;
namespace ascii  = boost::spirit::ascii;
namespace phx    = boost::phoenix;

namespace AST
{
    struct FunctionCall {};
    using Value = int;
}

template <typename Iterator>
struct Grammar : qi::grammar<Iterator, AST::FunctionCall(), ascii::space_type>
{
    Grammar(): Grammar::base_type(predicate)
    {
        using phx::bind;
        using namespace qi;

        as<PredicateArgList> coerce;

        predicate = 
            (pred_tbl > '('
                      > coerce [ -(primary_expr % ',') ]
                      > ')') 
            [ phx::bind(_1, this, _2)]
            ;

        pred_tbl.add
            ("composing",    &Grammar::composing)
        ;

        primary_expr = qi::int_;
    }

    typedef std::vector<AST::Value> PredicateArgList;
    typedef boost::function<void (Grammar*, PredicateArgList const&)> Predicate;   
    qi::symbols<char, Predicate> pred_tbl;

    qi::rule<Iterator, AST::Value(), ascii::space_type>   primary_expr;
    qi::rule<Iterator, AST::FunctionCall(), ascii::space_type>   predicate;

    void composing(const PredicateArgList& args) 
    {
        std::cout << "Hello world from 'Grammar::composing(PredicateArgList const&)' args:" << args.size() << "\n";
    }
};

int main()
{
    const std::string input("composing (1, 2, 3)");
    auto f = begin(input), l = end(input);

    Grammar<decltype(f)> p;

    bool ok = qi::phrase_parse(f,l,p,ascii::space);
    return ok?0:255;
}