Назначение парсеров для авто переменных
Разве спарсерские пароли не предназначены для использования с 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') >> ']');