Boost Spirit x3示例计算器(calc8,calc9)链接器错误

时间:2018-08-01 07:44:12

标签: boost linker-errors boost-spirit boost-spirit-x3

我对促进精神(和促进精神)很陌生。它非常有趣的库。

我使用qtcreator + MinGW 5.3。 我只是将git_hub_calc8中的每个源文件添加到新项目中,并添加了一些boost库,但是尝试构建时出现以下错误(所有其他示例都可以正常工作)

C:\Program Files\boost\boost\boost\spirit\home\x3\nonterminal\rule.hpp:113: ошибка: undefined reference to `bool client::parser::parse_rule<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::spirit::x3::context<boost::spirit::x3::error_handler_tag, std::reference_wrapper<boost::spirit::x3::error_handler<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, boost::spirit::x3::context<boost::spirit::x3::skipper_tag, boost::spirit::x3::char_class<boost::spirit::char_encoding::ascii, boost::spirit::x3::space_tag> const, boost::spirit::x3::unused_type> >, std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> > >(boost::spirit::x3::rule<client::parser::statement_class, std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> >, false>, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, boost::spirit::x3::context<boost::spirit::x3::error_handler_tag, std::reference_wrapper<boost::spirit::x3::error_handler<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, boost::spirit::x3::context<boost::spirit::x3::skipper_tag, boost::spirit::x3::char_class<boost::spirit::char_encoding::ascii, boost::spirit::x3::space_tag> const, boost::spirit::x3::unused_type> > const&, std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> >&)'

我怎么了?我应该如何使用此示例创建项目?

似乎是BOOST_SPIRIT_DECLARE的问题,因为错误指出的地方是调用与此定义关联的模板函数

(template <typename Iterator, typename Context, typename Attribute_>
        bool parse(Iterator& first, Iterator const& last
          , Context const& context, unused_type, Attribute_& attr) const
        {
            return parse_rule(*this, first, last, context, attr);
        }

1 个答案:

答案 0 :(得分:0)

BOOST_SPIRIT_INSTANTIATE marco等同于做

namespace client { namespace parser
{

    template bool parse_rule<iterator_type, context_type, statement_type::attribute_type>(
        statement_type rule_, iterator_type &first, iterator_type const &last,
        context_type const &context,
        statement_type ::attribute_type &attr);
                                                                        ;
}}

因此至关重要的一点是,iterator_typecontext_type与呼叫站点所需的完全匹配。现在,未解析的符号是(去角质):

bool client::parser::parse_rule<
    __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >,
    boost::spirit::x3::context<
        boost::spirit::x3::error_handler_tag,
        std::reference_wrapper<boost::spirit::x3::error_handler<__gnu_cxx::__normal_iterator<
            char const *, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >,
        boost::spirit::x3::context<
            boost::spirit::x3::skipper_tag,
            boost::spirit::x3::char_class<boost::spirit::char_encoding::ascii, boost::spirit::x3::space_tag> const,
            boost::spirit::x3::unused_type> >,
    std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> >
>
(boost::spirit::x3::rule<client::parser::statement_class, std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> >, false>,
__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&,
__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&,
    boost::spirit::x3::context<
        boost::spirit::x3::error_handler_tag,
        std::reference_wrapper<boost::spirit::x3::error_handler<__gnu_cxx::__normal_iterator<
            char const *, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >,
        boost::spirit::x3::context<
            boost::spirit::x3::skipper_tag,
            boost::spirit::x3::char_class<boost::spirit::char_encoding::ascii, boost::spirit::x3::space_tag> const,
            boost::spirit::x3::unused_type> > const &,
std::__cxx11::list<client::ast::statement, std::allocator<client::ast::statement> >&)

这意味着iterator_type应该为:

__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >,

std::string::const_iterator确实可以在我的系统上进行扩展。因此,不匹配可能是在上下文类型中。通过在BOOST_SPIRIT_INSTANTIATE调用上方添加强制类型错误,如下所示:

struct {} _ = *static_cast<client::parser::context_type*>(nullptr);

我能够在实例化时强制编译器输出context_type的扩展类型:

statement.cpp:12 error: conversion from ‘client::parser::context_type {aka boost::spirit::x3::context<boost::spirit::x3::error_handler_tag, const std::reference_wrapper<boost::spirit::x3::error_handler<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> > > >, boost::spirit::x3::context<boost::spirit::x3::skipper_tag, const boost::spirit::x3::char_class<boost::spirit::char_encoding::ascii, boost::spirit::x3::space_tag>, boost::spirit::x3::unused_type> >}’ to non-scalar type ‘client::parser::<anonymous struct>’ requested

这告诉我们上下文类型是(为便于阅读而格式化的):

boost::spirit::x3::context<
    boost::spirit::x3::error_handler_tag,
    const std::reference_wrapper<boost::spirit::x3::error_handler<
        __gnu_cxx::__normal_iterator<const char *, std::__cxx11::basic_string<char> > > >,
    boost::spirit::x3::context<
        boost::spirit::x3::skipper_tag,
        boost::spirit::x3::char_class<boost::spirit::char_encoding::ascii, boost::spirit::x3::space_tag> const,
        boost::spirit::x3::unused_type> >,

但是:链接器的名称为

boost::spirit::x3::context<
    boost::spirit::x3::error_handler_tag,
    std::reference_wrapper<boost::spirit::x3::error_handler<
        __gnu_cxx::__normal_iterator<const char *, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >,
    boost::spirit::x3::context<
        boost::spirit::x3::skipper_tag,
        boost::spirit::x3::char_class<boost::spirit::char_encoding::ascii, boost::spirit::x3::space_tag> const,
        boost::spirit::x3::unused_type> >

最明显的区别在于std::basic_stringchar_traitsallocator)上默认模板参数的拼写,但这实际上没有区别。不过,确实重要的区别是const类型与reference_wrapper<>的缺失。

修复

我想这可能是X3历史上的一次改变。在这种情况下,最简单的解决方法是将const放到config.hpp中:

typedef x3::context<
    error_handler_tag
  , std::reference_wrapper<error_handler_type>
  , phrase_context_type>
context_type;

事实上,它现在可以编译