boost::spirit 属性赋值:struct is_nullary: 基类型不能是 struct 或 class 类型
boost::spirit attribute assignment: struct is_nullary: base type fails to be a struct or class type
我有一个 boost::spirit
解析器,它应该简单地分配一个指向其属性的指针:
rule<CompoundExpression *(Scope &)> var_ref = var<CompoundExpression>()(_r1) [
_val = new_<Reference<Variable<CompoundExpression>>>(_1)
];
其中 var<CompoundExpression>()
是一个函数,它 returns 对执行实际解析的静态规则的引用。我在整个代码中对 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>>
类型看起来非常好,我可以从它构造对象,或者按我预期的方式使用它。
另外,问题似乎出在整个 phoenix 赋值表达式上,而不是它的 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
,这是不应该发生的。但是为什么会这样,我怎么会这样呢?
好的,看来我也需要
#include <boost/phoenix/object/dynamic_cast.hpp>
#include <boost/phoenix/operator/self.hpp>
为了使多态赋值起作用。一些我没有注意到的东西,因为它被间接包含在其他案例中。
我有一个 boost::spirit
解析器,它应该简单地分配一个指向其属性的指针:
rule<CompoundExpression *(Scope &)> var_ref = var<CompoundExpression>()(_r1) [
_val = new_<Reference<Variable<CompoundExpression>>>(_1)
];
其中 var<CompoundExpression>()
是一个函数,它 returns 对执行实际解析的静态规则的引用。我在整个代码中对 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>>
类型看起来非常好,我可以从它构造对象,或者按我预期的方式使用它。
另外,问题似乎出在整个 phoenix 赋值表达式上,而不是它的 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
,这是不应该发生的。但是为什么会这样,我怎么会这样呢?
好的,看来我也需要
#include <boost/phoenix/object/dynamic_cast.hpp>
#include <boost/phoenix/operator/self.hpp>
为了使多态赋值起作用。一些我没有注意到的东西,因为它被间接包含在其他案例中。