简体   繁体   中英

Boost Spirit x3 not compiling

I'm following the x3 documentation on the boost website, and I've tried to augment the example on how to organize code with the stuff explained in the annotations example that comes after. I'm having the following error when compiling the project (either with g++ or MSVC):

error: no matching function for call to 'boost::spirit::x3::unused_type::get()'

In the first line of function on_success in the following code:

// tag used to get the position cache from the context
struct annotate_position
{
    template <typename T, typename Iterator, typename Context>
    inline void on_success(const Iterator &first, const Iterator &last, T &ast, const Context &context)
    {
        auto &position_cache = x3::get<position_cache_tag>(context).get();
        position_cache.annotate(ast, first, last);
    }
};

Code can be found here: Github .

The annotations example is almost the exact same code, just in a single file, so I can't figure out what's wrong...

The annotation uses the with<> directive. That modifies the context for those rules.

The context, however, had been hard-coded in config.hpp because that enables the rule definitions to be separated in their own translation unit (source file).

To fix it directly:

struct position_cache_tag;
using position_cache = boost::spirit::x3::position_cache<std::vector<iterator_type>>;

using simple_context_type = x3::phrase_parse_context<x3::ascii::space_type>::type;

using context_type = boost::spirit::x3::context<
    client::parser::position_cache_tag,
    std::reference_wrapper<position_cache>, 
    simple_context_type
>;

That should already work. However, you'll find other things missing because the old parse function in main (without position annotations) was also still there. In principle adding a triplet like

BOOST_SPIRIT_INSTANTIATE(person_type, iterator_type, simple_context_type)
BOOST_SPIRIT_INSTANTIATE(employee_type, iterator_type, simple_context_type)
BOOST_SPIRIT_INSTANTIATE(employees_type, iterator_type, simple_context_type)

would be enough to alleviate, but then, obviously, the annotation code in on_success will not compile. If you want, you can SFINAE yourself out of that mess, but I just removed the unused code from main.cpp .

BONUS

As a bonus, you can do without the reference_wrapper these days, since I see you're using Boost 1.70.

The reference-wrapper used to be required for mutable state in with directives, but I found out recently ( Spirit X3, Is this error handling approach useful? ) that that's no longer required. Therefore you can simplify the context:

using context_type = boost::spirit::x3::context<
    client::parser::position_cache_tag,
    position_cache, 
    simple_context_type
>;

And drop the reference wrapper on both ends:

auto &position_cache = x3::get<position_cache_tag>(context); // NOTE: no more .get()

And

auto const parser =
    with<position_cache_tag>(positions)[client::employees()];

Full Code (Github)

Here's my working code: https://github.com/sehe/corrupted-spirit containing the following commits in order, so it's easy to find what changed why:

commit 2d1d553afab53d7a83620406c2dcd50967bf2765
Date:   Wed Jul 31 22:50:49 2019 +0200

    Build tweaks

    Make it compile on my linux box, and adding some minimum
    debug/sanitizer/diagnostics flags

commit 98a989bb165d0b25b6919449d4dd09f7656168c8
Date:   Wed Jul 31 22:51:50 2019 +0200

    Various compiler wanrings, no impact

commit 91f5c607c10a489e2d7b9e45dca55438d05419a2
Date:   Wed Jul 31 22:53:46 2019 +0200

    Fixed style issues in main.cpp

     - using namespace (my first hunch was with `ref` being std::ref instead
     of boost::ref, but that turned out a red herring. Better to be explicit
     though

     - added condition on use of ast[1]

commit 084700c80023d4fb291bee36f41cb99f23f7dffa
Date:   Wed Jul 31 22:51:20 2019 +0200

    Fix the context_type in config.hpp

commit df7f9505e042b93bcd62167090e89008788218de (HEAD -> master, sehe/master)
Date:   Wed Jul 31 22:56:20 2019 +0200

    Simplify the with directive

    1.70.0 no longer requires manual ref() for with directives with mutable
    context items.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM