尝试解析 Boost Spirit 语法时出现编译时错误

Compile-time error when trying to parse a Boost Spirit grammar

尝试编译以下代码(根据我的原始代码创建的最小示例)会出现下面列出的错误。

问题似乎出在行 qi::phrase_parse(first, str.end(), grammar, ascii::blank); 上,但我不知道这可能有什么问题。删除该行会导致代码编译成功,因此语法定义本身似乎没有任何问题。

This SO question 报告了类似的错误,但我在答案中找不到任何适用的内容。

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

using namespace std;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

template <typename Iterator>
class DoubleGrammar : qi::grammar<Iterator, ascii::blank_type> {
private:
    qi::rule<Iterator, ascii::blank_type> double_rule;
public:
    DoubleGrammar() : DoubleGrammar::base_type(double_rule) {
        double_rule = qi::double_;
    }
};

int main(int argc, char** argv) {
    DoubleGrammar<string::iterator> grammar;
    string str = "1.0";
    string::iterator first = str.begin();
    qi::phrase_parse(first, str.end(), grammar, ascii::blank);
    return 0;
}

编译器输出:

In file included from /usr/include/boost/proto/traits.hpp:24:0,
                 from /usr/include/boost/proto/expr.hpp:27,
                 from /usr/include/boost/proto/core.hpp:17,
                 from /usr/include/boost/proto/proto.hpp:12,
                 from /usr/include/boost/spirit/home/support/meta_compiler.hpp:19,
                 from /usr/include/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /usr/include/boost/spirit/home/qi/action/action.hpp:14,
                 from /usr/include/boost/spirit/home/qi/action.hpp:14,
                 from /usr/include/boost/spirit/home/qi.hpp:14,
                 from /usr/include/boost/spirit/include/qi.hpp:16,
                 from .build/test/spirittest.cpp:4:
/usr/include/boost/spirit/home/qi/detail/parse.hpp: In instantiation of 'struct boost::spirit::qi::detail::phrase_parse_impl<DoubleGrammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >, void>':
/usr/include/boost/spirit/home/qi/detail/parse_auto.hpp:186:50:   required from 'bool boost::spirit::qi::phrase_parse(Iterator&, Iterator, Expr&, const Skipper&, boost::spirit::qi::skip_flag) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; Expr = DoubleGrammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >; Skipper = boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >, 0l>]'
.build/test/spirittest.cpp:62:61:   required from here
/usr/include/boost/spirit/home/qi/detail/parse.hpp:59:9: error: static assertion failed: error_invalid_expression
         BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
         ^
In file included from /usr/include/boost/spirit/home/qi/auto.hpp:16:0,
                 from /usr/include/boost/spirit/home/qi.hpp:15,
                 from /usr/include/boost/spirit/include/qi.hpp:16,
                 from .build/test/spirittest.cpp:4:
/usr/include/boost/spirit/home/qi/detail/parse_auto.hpp: In instantiation of 'bool boost::spirit::qi::phrase_parse(Iterator&, Iterator, Expr&, const Skipper&, boost::spirit::qi::skip_flag) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; Expr = DoubleGrammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >; Skipper = boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank, boost::spirit::char_encoding::ascii> >, 0l>]':
.build/test/spirittest.cpp:62:61:   required from here
/usr/include/boost/spirit/home/qi/detail/parse_auto.hpp:186:50: error: 'call' is not a member of 'boost::spirit::qi::detail::phrase_parse_impl<DoubleGrammar<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >, void>'
             first, last, expr, skipper, post_skip);
                                                  ^

我实际上是在相关问题列表中找到的 this SO answer 的帮助下找到了答案。

问题是 DoubleGrammar class 私下继承了 qi::grammar。添加 public 可见性说明符解决了问题。

这是错误的,因为它所基于的示例使用了一个默认具有 public 可见性的结构。