Compile error with boost::spirit::x3

拟墨画扇 提交于 2021-01-29 05:14:32

问题


I tried to compile example file with gcc 5.3.1 (5.3.1 20160406 (Red Hat 5.3.1-6) (GCC)), boost 1.61.0.

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/home/x3.hpp>

#include <iostream>

// Presented are various ways to attach semantic actions
//  * Using plain function pointer
//  * Using simple function object

namespace client
{
    namespace x3 = boost::spirit::x3;
    using x3::_attr;

    struct print_action
    {    
        template <typename Context>
        void operator()(Context const& ctx) const
        {
            std::cout << _attr(ctx) << std::endl;
        }
    };
}

int main()
{
    using boost::spirit::x3::int_;
    using boost::spirit::x3::parse;
    using client::print_action;

    { // example using function object

        char const *first = "{43}", *last = first + std::strlen(first);
        parse(first, last, '{' >> int_[print_action()] >> '}');
    }

    { // example using C++14 lambda

        char const *first = "{44}", *last = first + std::strlen(first);
        auto f = [](auto& ctx){ std::cout << _attr(ctx) << std::endl; };
        parse(first, last, '{' >> int_[f] >> '}');
    }

    return 0;
}

The compile command is:g++ test.cpp -std=c++1y (I just renamed the file.)

I got the following error:

test.cpp: In instantiation of ‘main()::<lambda(auto:1&)> [with auto:1 = const boost::spirit::x3::context<boost::spirit::x3::attr_context_tag, int, boost::spirit::x3::context<boost::spirit::x3::where_context_tag, boost::iterator_range<const char*>, boost::spirit::x3::context<boost::spirit::x3::rule_val_context_tag, const boost::spirit::x3::unused_type, boost::spirit::x3::context<boost::spirit::x3::parse_pass_context_tag, bool, boost::spirit::x3::unused_type> > > >]’:
/usr/local/include/boost/spirit/home/x3/support/utility/is_callable.hpp:20:35:   required from ‘struct boost::spirit::x3::is_callable<main()::<lambda(auto:1&)>(const boost::spirit::x3::context<boost::spirit::x3::attr_context_tag, int, boost::spirit::x3::context<boost::spirit::x3::where_context_tag, boost::iterator_range<const char*>, boost::spirit::x3::context<boost::spirit::x3::rule_val_context_tag, const boost::spirit::x3::unused_type, boost::spirit::x3::context<boost::spirit::x3::parse_pass_context_tag, bool, boost::spirit::x3::unused_type> > > >&)>’
/usr/local/include/boost/spirit/home/x3/core/call.hpp:72:28:   required from ‘auto boost::spirit::x3::call(F, Iterator&, const Iterator&, const Context&, RuleContext&, Attribute&) [with F = main()::<lambda(auto:1&)>; Iterator = const char*; Context = boost::spirit::x3::context<boost::spirit::x3::parse_pass_context_tag, bool, boost::spirit::x3::unused_type>; RuleContext = const boost::spirit::x3::unused_type; Attribute = int]’
/usr/local/include/boost/spirit/home/x3/core/action.hpp:45:17:   required from ‘bool boost::spirit::x3::action<Subject, Action>::call_action(Iterator&, const Iterator&, const Context&, RuleContext&, Attribute&) const [with Iterator = const char*; Context = boost::spirit::x3::unused_type; RuleContext = const boost::spirit::x3::unused_type; Attribute = int; Subject = boost::spirit::x3::int_parser<int>; Action = main()::<lambda(auto:1&)>]’
/usr/local/include/boost/spirit/home/x3/core/action.hpp:57:32:   required from ‘bool boost::spirit::x3::action<Subject, Action>::parse_main(Iterator&, const Iterator&, const Context&, RuleContext&, Attribute&) const [with Iterator = const char*; Context = boost::spirit::x3::unused_type; RuleContext = const boost::spirit::x3::unused_type; Attribute = int; Subject = boost::spirit::x3::int_parser<int>; Action = main()::<lambda(auto:1&)>]’
/usr/local/include/boost/spirit/home/x3/operator/sequence.hpp:32:17:   recursively required from ‘bool boost::spirit::x3::sequence<Left, Right>::parse(Iterator&, const Iterator&, const Context&, RContext&, boost::spirit::x3::unused_type) const [with Iterator = const char*; Context = boost::spirit::x3::unused_type; RContext = const boost::spirit::x3::unused_type; Left = boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>; Right = boost::spirit::x3::action<boost::spirit::x3::int_parser<int>, main()::<lambda(auto:1&)> >]’
/usr/local/include/boost/spirit/home/x3/operator/sequence.hpp:32:17:   required from ‘bool boost::spirit::x3::sequence<Left, Right>::parse(Iterator&, const Iterator&, const Context&, RContext&, boost::spirit::x3::unused_type) const [with Iterator = const char*; Context = boost::spirit::x3::unused_type; RContext = const boost::spirit::x3::unused_type; Left = boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::int_parser<int>, main()::<lambda(auto:1&)> > >; Right = boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>]’
/usr/local/include/boost/spirit/home/x3/core/parse.hpp:35:68:   required from ‘bool boost::spirit::x3::parse_main(Iterator&, Iterator, const Parser&, Attribute&) [with Iterator = const char*; Parser = boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::int_parser<int>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type> >; Attribute = const boost::spirit::x3::unused_type]’
/usr/local/include/boost/spirit/home/x3/core/parse.hpp:71:26:   required from ‘bool boost::spirit::x3::parse(Iterator&, Iterator, const Parser&) [with Iterator = const char*; Parser = boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::int_parser<int>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type> >]’
test.cpp:47:49:   required from here
test.cpp:46:51: 错误:use of ‘template<class Context> decltype(auto) boost::spirit::x3::_attr(const Context&)’ before deduction of ‘auto’
         auto f = [](auto& ctx){ std::cout << _attr(ctx) << std::endl; };
                                                   ^
test.cpp:46:51: 错误:use of ‘decltype(auto) boost::spirit::x3::_attr(const Context&) [with Context = boost::spirit::x3::context<boost::spirit::x3::attr_context_tag, int, boost::spirit::x3::context<boost::spirit::x3::where_context_tag, boost::iterator_range<const char*>, boost::spirit::x3::context<boost::spirit::x3::rule_val_context_tag, const boost::spirit::x3::unused_type, boost::spirit::x3::context<boost::spirit::x3::parse_pass_context_tag, bool, boost::spirit::x3::unused_type> > > >]’ before deduction of ‘auto’
In file included from /usr/local/include/boost/spirit/home/x3/core/action.hpp:13:0,
                 from /usr/local/include/boost/spirit/home/x3/core.hpp:14,
                 from /usr/local/include/boost/spirit/home/x3.hpp:20,
                 from test.cpp:8:
/usr/local/include/boost/spirit/home/x3/core/call.hpp: In instantiation of ‘auto boost::spirit::x3::call(F, Iterator&, const Iterator&, const Context&, RuleContext&, Attribute&) [with F = main()::<lambda(auto:1&)>; Iterator = const char*; Context = boost::spirit::x3::context<boost::spirit::x3::parse_pass_context_tag, bool, boost::spirit::x3::unused_type>; RuleContext = const boost::spirit::x3::unused_type; Attribute = int]’:
/usr/local/include/boost/spirit/home/x3/core/action.hpp:45:17:   required from ‘bool boost::spirit::x3::action<Subject, Action>::call_action(Iterator&, const Iterator&, const Context&, RuleContext&, Attribute&) const [with Iterator = const char*; Context = boost::spirit::x3::unused_type; RuleContext = const boost::spirit::x3::unused_type; Attribute = int; Subject = boost::spirit::x3::int_parser<int>; Action = main()::<lambda(auto:1&)>]’
/usr/local/include/boost/spirit/home/x3/core/action.hpp:57:32:   required from ‘bool boost::spirit::x3::action<Subject, Action>::parse_main(Iterator&, const Iterator&, const Context&, RuleContext&, Attribute&) const [with Iterator = const char*; Context = boost::spirit::x3::unused_type; RuleContext = const boost::spirit::x3::unused_type; Attribute = int; Subject = boost::spirit::x3::int_parser<int>; Action = main()::<lambda(auto:1&)>]’
/usr/local/include/boost/spirit/home/x3/operator/sequence.hpp:32:17:   recursively required from ‘bool boost::spirit::x3::sequence<Left, Right>::parse(Iterator&, const Iterator&, const Context&, RContext&, boost::spirit::x3::unused_type) const [with Iterator = const char*; Context = boost::spirit::x3::unused_type; RContext = const boost::spirit::x3::unused_type; Left = boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>; Right = boost::spirit::x3::action<boost::spirit::x3::int_parser<int>, main()::<lambda(auto:1&)> >]’
/usr/local/include/boost/spirit/home/x3/operator/sequence.hpp:32:17:   required from ‘bool boost::spirit::x3::sequence<Left, Right>::parse(Iterator&, const Iterator&, const Context&, RContext&, boost::spirit::x3::unused_type) const [with Iterator = const char*; Context = boost::spirit::x3::unused_type; RContext = const boost::spirit::x3::unused_type; Left = boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::int_parser<int>, main()::<lambda(auto:1&)> > >; Right = boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>]’
/usr/local/include/boost/spirit/home/x3/core/parse.hpp:35:68:   required from ‘bool boost::spirit::x3::parse_main(Iterator&, Iterator, const Parser&, Attribute&) [with Iterator = const char*; Parser = boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::int_parser<int>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type> >; Attribute = const boost::spirit::x3::unused_type]’
/usr/local/include/boost/spirit/home/x3/core/parse.hpp:71:26:   required from ‘bool boost::spirit::x3::parse(Iterator&, Iterator, const Parser&) [with Iterator = const char*; Parser = boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::int_parser<int>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type> >]’
test.cpp:47:49:   required from here
/usr/local/include/boost/spirit/home/x3/core/call.hpp:72:28: 错误:use of ‘auto boost::spirit::x3::detail::call(F, const Context&, mpl_::true_) [with F = main()::<lambda(auto:1&)>; Context = boost::spirit::x3::context<boost::spirit::x3::attr_context_tag, int, boost::spirit::x3::context<boost::spirit::x3::where_context_tag, boost::iterator_range<const char*>, boost::spirit::x3::context<boost::spirit::x3::rule_val_context_tag, const boost::spirit::x3::unused_type, boost::spirit::x3::context<boost::spirit::x3::parse_pass_context_tag, bool, boost::spirit::x3::unused_type> > > >; mpl_::true_ = mpl_::bool_<true>]’ before deduction of ‘auto’
         return detail::call(f, attr_context, is_callable<F(decltype(attr_context) const&)>());
                            ^

I wonder what leads to this error?

P.S: In the file, 错误 means Error.


回答1:


Note It looks like you linked the wrong sample file. My answer responds to the code shown in the error message instead.

I can't reproduce the problem, but I remember seeing something similar once.

It seems GCC sometimes has trouble doing ADL for a polymorphic lambda parameter type.

The way I got around it was to disable ADL there:

auto f = [](auto& ctx){ std::cout << x3::_attr(ctx) << std::endl; };

or:

auto f = [](auto& ctx){ std::cout << (_attr)(ctx) << std::endl; };


来源:https://stackoverflow.com/questions/38199320/compile-error-with-boostspiritx3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!