【问题标题】:Unable to convert boost::fusion struct in boost::variant while using boost::spirit使用 boost::spirit 时无法在 boost::variant 中转换 boost::fusion 结构
【发布时间】:2012-12-06 20:14:03
【问题描述】:

美好的时光!

我写了这段代码,希望它能够被编译。

#include <string>

#include <boost/spirit/include/qi.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/fusion/include/adapted.hpp>

struct ParsedThunk
{
    typedef boost::variant<std::string, boost::tuple<boost::recursive_wrapper<ParsedThunk>, boost::recursive_wrapper<ParsedThunk> > > ParsedThunkEntity;
    ParsedThunkEntity _entity;
};

BOOST_FUSION_ADAPT_STRUCT(
    ParsedThunk,
    (ParsedThunk::ParsedThunkEntity, _entity)
)

class ThunkParser
{
protected:
    boost::spirit::qi::rule<std::string::iterator, ParsedThunk(), boost::spirit::ascii::space_type> _thunkRule;

public:
    ThunkParser()
    {
        _thunkRule %= (
            (boost::spirit::qi::lexeme[+(boost::spirit::qi::char_ - boost::spirit::qi::char_(" =()"))]) | 
            (boost::spirit::qi::lit("(") >> _thunkRule >> _thunkRule >> boost::spirit::qi::lit(")")) | 
            (_thunkRule >> _thunkRule)
            ) >> boost::spirit::qi::eps;
    }
};

int main(void)
{
    return 0;
}

但是当我用 clang 或 GCC 编译它时,我得到一个错误。其中最有趣的部分是:

/usr/include/boost/variant/detail/initializer.hpp:89:24: note: candidate function not viable: no known conversion from 'const boost::fusion::vector2<ParsedThunk, ParsedThunk>' to 'const
      boost::tuples::tuple<boost::recursive_wrapper<ParsedThunk>, boost::recursive_wrapper<ParsedThunk>, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
      boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>' for 2nd argument;
            static int initialize(void* dest, param_T operand)

我使用 clang 3.1 或 gcc 4.7 和 boost 1.52,但我认为没关系。 :)

我应该如何编辑这段代码以使其被编译?

更新

好吧,我刚刚注意到我指定的语法是左递归的,因此递归下降解析器在处理输入时可能不会停止。这可能是编译问题的原因吗?

【问题讨论】:

    标签: c++ boost boost-spirit boost-variant boost-fusion


    【解决方案1】:

    修正您的变体类型:

    typedef boost::variant<
                std::string,
                boost::recursive_wrapper<boost::tuple<ParsedThunk, ParsedThunk> >
            > ParsedThunkEntity;
    

    【讨论】:

    • 您能解释一下为什么boost::recursive_wrapper&lt;boost::tuple&lt;ParsedThunk, ParsedThunk&gt; &gt; 应该可以工作,而boost::tuple&lt;boost::recursive_wrapper&lt;ParsedThunk&gt;, boost::recursive_wrapper&lt;ParsedThunk&gt; &gt; 不应该吗?我想了解。
    • “顶层”包装器防止类型定义非法(通过“延迟”嵌套类型)。您使用的“叶子”包装器阻止了通常的属性传播,因为boost::spirit::traits 不专门用于recursive_wrapper&lt;T&gt;。所以顶层包装器既足够又方便。
    • 好的,谢谢你的解释。我将在 12 小时内检查此解决方案并将答案标记为已接受。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    相关资源
    最近更新 更多