Assegnazione di parser a variabili automatiche

Gli analizzatori di spiriti non sono pensati per essere usati con l’ auto ?

Un semplice parser funziona bene quando viene passato a qi::parse() inline, ma si blocca con segfault se viene passato tramite una variabile auto :

 #include  #include  #include  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 } 

Riproduzioni con g ++ – 4.8 e VC13.

Aggiornamento: è stato corretto un errore nel codice originale ( p non è stato reinizializzato prima della seconda chiamata a parse() ).

Gli Spirit Parser non sono progettati per essere utilizzati con auto in Spirit V2.

Questo perché i modelli di espressione di Proto sottostanti contengono riferimenti ai provvisori.

Puoi usare

  • qi::copy() (esistente nel bagagliaio dopo boost_1_55_0, non in nessuna versione rilasciata in questo momento)
  • boost::proto::deep_copy
  • o BOOST_SPIRIT_AUTO (prima coniato qui )

Ho scritto su queste cose più spesso su SO: https://stackoverflow.com/search?q=user%3A85371+deep_copy , in particolare, questo:

  • boost spirit V2 qi bug associato al livello di ottimizzazione

Boost Spirit X3 non avrà questa limitazione.

Boost.Spirit utilizza modelli di espressioni e non funziona con auto . Una soluzione alternativa è usare boost::proto::deep_copy :

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