назначение boost :: phoenix не скомпилируется - PullRequest
0 голосов
/ 01 марта 2019

У меня есть boost::spirit парсер, который должен просто назначить указатель на его атрибут:

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

, где var<CompoundExpression>() - это функция just, которая возвращает ссылку на статическое правило, которое выполняетфактический разбор.Я использую одно и то же действие присваивания с другими экземплярами шаблона 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 typedef'd как 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 голосов
/ 02 марта 2019

ОК, похоже, мне также нужно

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

, чтобы полиморфное назначение работало.Что-то, что я не заметил, потому что это было косвенно включено в другие случаи.

...