提升变异的精神继承

时间:2014-03-31 15:33:42

标签: c++ parsing boost boost-spirit

是否无法继承boost :: variant并将结果类用作选择运算符结果?

struct jass_statement_node {
};

typedef boost::variant<
boost::recursive_wrapper<jass_set>
, boost::recursive_wrapper<jass_call>
, boost::recursive_wrapper<jass_ifthenelse>
, boost::recursive_wrapper<jass_loop>
, boost::recursive_wrapper<jass_exitwhen>
, boost::recursive_wrapper<jass_return>
, boost::recursive_wrapper<jass_debug>
> jass_statement_base;

struct jass_statement : public jass_statement_node, public jass_statement_base {
};

...

statement %=
    set
    | call
    | ifthenelse
    | loop
    | exitwhen
    | return_statement
    | debug
;

会导致attr_cast错误。如果我使用base作为属性它可以工作,但我必须调整结构:

struct jass_statement : public jass_statement_node {
    jass_statement_base value;
};

BOOST_FUSION_ADAPT_STRUCT(
jass_statement,
(jass_statement_base, value)
)

1 个答案:

答案 0 :(得分:1)

快速检查

#include <boost/spirit/include/qi.hpp>

using V = boost::variant<int, double, std::string>;

struct my_struct : V {
};

int main()
{
    std::string const input("3.14151926");

    auto f(begin(input)), l(end(input));
    using namespace boost::spirit::qi;

    V parsed;
    bool ok = phrase_parse(
            f, l,
              lexeme [ '"' >> *~char_('"') >> '"' ]                // string
            | real_parser<double, strict_real_policies<double> >() // double
            | int_                                                 // well, int :)
        , space, parsed);

    return ok? 1 : 2;
}

确认这确实不是问题。因此,它与其他规则与变体元素类型的精确兼容性有关。

您可以专门为您的类型分配/转换特征:

namespace boost { namespace spirit { namespace traits {

    template <typename Exposed, typename Domain>
    struct transform_attribute<Exposed, my_struct, Domain, void> :
        transform_attribute<Exposed, V, Domain, void> { 
            using base_type = transform_attribute<Exposed, V, Domain, void>;
            using typename base_type::type;

            //static type pre(Exposed& val)             { return base_type::pre(val); }
            //static void post(Exposed& val, type attr) { base_type::post(val, attr); }
            //static void fail(Exposed&e)               { base_type::fail(e); }
        };
} } }

你可以试试这个(我希望这次没有让ExposedTransformed再次混淆:))

请参阅上面的 Live On Coliru