2014-02-25 12 views
6

Sind Spirit-Parser nicht für die Verwendung mit auto vorgesehen?Zuweisen von Parsern zu automatischen Variablen

Ein einfacher Parser funktioniert gut, wenn zu qi::parse() Inline vergangen, aber stürzt mit segfault wenn über eine auto Variable übergeben:

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

Reproes mit g ++ - 4.8 und VC13.

Update: Fehler in dem Original-Code festgelegt wurden (p wurde nicht neu initialisiert vor dem zweiten Aufruf parse()).

+0

Wie kann jeder C++ Parser mit 'auto' umgehen? Parser sollen bestimmte Typen lesen, die zur Laufzeit bestimmt werden, 'automatische' Typen werden zur Kompilierungszeit aufgelöst. Also IMHO, außer das 'auto' resultiert in' boost :: variant' oder 'boost :: any' ist nicht möglich. –

+1

Beachten Sie, dass der erste Iterator als Referenz (IIRC) übergeben wird. Das heißt, "p" wurde nach dem ersten Aufruf von 'qi :: parse' geändert. – dyp

+0

Danke, @dyp. Der Fehler wurde behoben. – mstone

Antwort

9

Geist Parser ist so konzipiert, nicht mit auto in Spirit V2 verwendet werden.

Dies liegt daran, dass die zugrunde liegenden Proto-Expressionsvorlagen Verweise auf die Provisorien enthalten.

können Sie verwenden

  • qi::copy() (bestehend im Kofferraum nach boost_1_55_0, in keiner freigegebenen Version zu dieser Zeit)
  • boost::proto::deep_copy
  • oder BOOST_SPIRIT_AUTO (erster here geprägt)

Ich habe über diese Dinge öfter auf SO geschrieben: https://stackoverflow.com/search?q=user%3A85371+deep_copy, speziell das:

Boost-Geist X3 wird diese Einschränkung nicht haben.

+1

Der Fehler ist in letzter Zeit zu oft aufgetreten. Daher gibt es die Notwendigkeit, eine zeitgemäße Version der Boost.Spirit Qi-Bibliothek zu haben, die C++ 11/C++ 1y vollständig aktiviert haben muss (ich denke, sie sollte zumindest Unterstützung für move-semantic enthalten). – Orient

+2

@Dukales Dies scheint eine Meinung zu sein, die Zitat benötigt :) Wenn Sie meinen, dass Sie begierig sind, Spirit X3 zu sehen, +1 – sehe

3

Boost.Spirit verwendet Expressionsvorlagen und funktioniert nicht mit auto. Eine Abhilfe ist boost::proto::deep_copy zu verwenden:

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