Назначение парсеров для авто переменных

Разве спарсерские пароли не предназначены для использования с auto?

Простой парсер работает нормально, когда передается qi::parse() встроенный, но падает с segfault, если передается через auto переменная:

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

using namespace std;

namespace qi = boost::spirit::qi;

int main()
{
    string line = "[z]";

    auto bracketed_z = '[' >> +qi::char_('z') >> ']';

    auto p = line.cbegin();
    printf("%d", qi::parse(p, line.cend(), '[' >> +qi::char_('z') >> ']'));  // Works

    p = line.cbegin();
    printf("%d", qi::parse(p, line.cend(), bracketed_z));                    // Crashes
}

Воспроизводит с g++-4.8 и VC13.

Обновление: ошибка была исправлена ​​в исходном коде (p не был повторно инициализирован перед вторым вызовом parse()).

2 ответа

Решение

Духовые парсеры не предназначены для использования с auto в духе V2.

Это потому, что базовые шаблоны выражений Proto содержат ссылки на временные.

Ты можешь использовать

  • qi::copy() (существует в багажнике после boost_1_55_0, но не в какой-либо выпущенной версии в настоящее время)
  • boost::proto::deep_copy
  • или BOOST_SPIRIT_AUTO (впервые придумано здесь)

Я писал об этих вещах чаще всего на SO: https://stackru.com/search?q=user%3A85371+deep_copy, в частности, это:

Boost Spirit X3 не будет иметь этого ограничения.

Boost.Spirit использует шаблоны выражений и не работает с auto, Обходной путь должен использовать boost::proto::deep_copy:

auto bracketed_z = proto::deep_copy('[' >> +qi::char_('z') >> ']');
Другие вопросы по тегам