boost :: phoenix分配不会编译

时间:2019-03-01 20:49:24

标签: c++ boost boost-spirit boost-phoenix

我有一个boost::spirit解析器,该解析器应该简单地为其属性分配一个指针:

rule<CompoundExpression *(Scope &)> var_ref = var<CompoundExpression>()(_r1) [
    _val = new_<Reference<Variable<CompoundExpression>>>(_1)
];

其中var<CompoundExpression>()是一个正义函数,它返回对执行实际解析的静态规则的引用。我在代码中对Reference<Variable<T>>模板的其他实例化使用了相同的赋值操作,这很好,除了使用CompoundExpression参数的模板之外。

文字上的GCC错误是这样的:

In file included from /usr/include/boost/phoenix/core/actor.hpp:20,
                 from /usr/include/boost/phoenix/core.hpp:12,
                 from /usr/include/boost/spirit/include/phoenix_core.hpp:11,
                 from /usr/include/boost/spirit/home/support/argument.hpp:18,
                 from /usr/include/boost/spirit/home/qi/nonterminal/rule.hpp:29,
                 from /usr/include/boost/spirit/home/qi/nonterminal.hpp:14,
                 from /usr/include/boost/spirit/include/qi_nonterminal.hpp:16,
                 from /home/ich/sync/ConTrAkt/gologpp/src/parser/utilities.h:7,
                 from /home/ich/sync/ConTrAkt/gologpp/src/parser/compound_expression.h:4,
                 from /home/ich/sync/ConTrAkt/gologpp/src/parser/compound_expression.cpp:1:
/usr/include/boost/phoenix/core/is_nullary.hpp: In instantiation of ‘struct boost::phoenix::result_of::is_nullary<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::attribute<0> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::new_, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::detail::target<gologpp::Reference<gologpp::Variable<gologpp::TypedExpression<gologpp::CompoundType> > > > >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2>, void>’:
/usr/include/boost/phoenix/core/actor.hpp:178:13:   required from ‘struct boost::phoenix::result_of::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::attribute<0> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::new_, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::detail::target<gologpp::Reference<gologpp::Variable<gologpp::TypedExpression<gologpp::CompoundType> > > > >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2> >’
/usr/include/boost/phoenix/core/actor.hpp:271:9:   required from ‘struct boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::attribute<0> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::new_, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::detail::target<gologpp::Reference<gologpp::Variable<gologpp::TypedExpression<gologpp::CompoundType> > > > >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2> >’
/home/ich/sync/ConTrAkt/gologpp/src/parser/compound_expression.cpp:22:58:   required from here
/usr/include/boost/phoenix/core/is_nullary.hpp:115:16: error: base type ‘boost::phoenix::evaluator::impl<const boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::attribute<0> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::new_, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::detail::target<gologpp::Reference<gologpp::Variable<gologpp::TypedExpression<gologpp::CompoundType> > > > >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2>&, boost::phoenix::vector2<mpl_::bool_<true>, boost::phoenix::is_nullary>, boost::proto::envns_::empty_env>::result_type’ {aka ‘const boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::attribute<0> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::new_, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::detail::target<gologpp::Reference<gologpp::Variable<gologpp::TypedExpression<gologpp::CompoundType> > > > >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2>&’} fails to be a struct or class type
         struct is_nullary
                ^~~~~~~~~~

由于几乎无法读取,因此我将尝试clang-format。所以我想这要归结到最后一行:

/usr/include/boost/phoenix/core/is_nullary.hpp:115:16: error: base type
‘boost::phoenix::evaluator::impl<
    const boost::proto::exprns_::basic_expr<
        boost::proto::tagns_::tag::assign,
        boost::proto::argsns_::list2<
            boost::proto::exprns_::expr<
                boost::proto::tagns_::tag::terminal,
                boost::proto::argsns_::term<boost::spirit::attribute<0>>, 0>,
            boost::phoenix::actor<boost::proto::exprns_::basic_expr<
                boost::phoenix::tag::new_,
                boost::proto::argsns_::list2<
                    boost::proto::exprns_::basic_expr<
                        boost::proto::tagns_::tag::terminal,
                        boost::proto::argsns_::term<
                            boost::phoenix::detail::target<gologpp::Reference<
                                gologpp::Variable<gologpp::TypedExpression<
                                    gologpp::CompoundType>>>>>,
                        0>,
                    boost::phoenix::actor<boost::spirit::argument<0>>>,
                2>>>,
        2> &,
    boost::phoenix::vector2<mpl_::bool_<true>, boost::phoenix::is_nullary>,
    boost::proto::envns_::empty_env>::result_type’ {
    aka ‘const boost::proto::exprns_::basic_expr<
        boost::proto::tagns_::tag::assign,
        boost::proto::argsns_::list2<
            boost::proto::exprns_::expr<
                boost::proto::tagns_::tag::terminal,
                boost::proto::argsns_::term<boost::spirit::attribute<0>>, 0>,
            boost::phoenix::actor<boost::proto::exprns_::basic_expr<
                boost::phoenix::tag::new_,
                boost::proto::argsns_::list2<
                    boost::proto::exprns_::basic_expr<
                        boost::proto::tagns_::tag::terminal,
                        boost::proto::argsns_::term<
                            boost::phoenix::detail::target<gologpp::Reference<
                                gologpp::Variable<gologpp::TypedExpression<
                                    gologpp::CompoundType>>>>>,
                        0>,
                    boost::phoenix::actor<boost::spirit::argument<0>>>,
                2>>>,
        2> &’}
fails to be a struct or class type

请注意,将gologpp::TypedExpression<gologpp::CompoundType的类型定义为gologpp::CompoundExpression

现在,如果我没看错的话,这种result_of::is_nullary的基本类型(/usr/include/boost/phoenix/core/is_nullary.hpp:115)某种程度上是引用类型,那就是问题。我的Reference<Variable<CompoundExpression>>类型看起来非常好,我可以从中构造对象并按预期使用它。 同样,问题似乎在于整个凤凰分配表达式,而不是其LHS或RHS。

查看boost / phoenix / core / is_nullary.hpp:115:

        struct is_nullary
            : boost::phoenix::evaluator::impl<
                Expr const &
              , vector2<
                    mpl::true_
                  , boost::phoenix::is_nullary
                >
              , proto::empty_env
            >::result_type
        {};

似乎Expr const &(在我的情况下是赋值表达式)正变得result_type,这是不应该发生的。但是,为什么会这样,又怎么引起呢?

1 个答案:

答案 0 :(得分:3)

好的,看来我也需要

#include <boost/phoenix/object/dynamic_cast.hpp>
#include <boost/phoenix/operator/self.hpp>

用于多态分配工作。我没有注意到的东西,因为它是间接包含在其他情况下的。