<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Wie kann ich Boost::Spirit mit meiner Callback-Funktion füttern?]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>Ich habe mir mit Boost::Spirit einen Parser für BibTex-Dateien geschrieben, der im Prinzip bereits funktioniert. Nun möchte ich das gute Stück aber in eine Klasse verpacken, welche mir eine BibTex-Datei verwaltet. Dabei werden die Callback-Funktionen zum Problem.<br />
Bis jetzt ging es so:</p>
<pre><code>std::string stack;
rule&lt;&gt; rule_wert = (rule_quote &gt;&gt; rule_txtmatch_quote [out&lt;const char*&gt;(stack)] &gt;&gt; rule_quote)
</code></pre>
<p>Dabei war out&lt;typename itT&gt;() ein Funktor, welcher dafür sorgt, dass Ausdrücke, die auf rule_txtmatch_quote passen im string Stack gespeichert werden.<br />
Jetzt habe ich aber den Parser und die Callback-Funktionen als Methoden in meine BibTex-klasse gepackt. Die Callback Funktion soll die geparsten Ausdrücke in einem Containerobjekt ablegen. Das soll in etwa so aussehen:</p>
<pre><code>class bibliography{

   ...

private:
   row _columns;
   std::vector&lt;row&gt; _rows;

   template&lt;typename iterator_t&gt;
   void addValue(file_iterator begin, file_iterator end);

   ...

   template&lt;typename iterator_t&gt;
   bool parse(iterator_t begin, iterator_t end);
}
</code></pre>
<p>Aber wie kann ich jetzt innerhalb meiner parse()-Funktion die Funktion addValue() übergeben. Ich habe zahlreiche Varianten versucht:</p>
<pre><code>rule&lt;&gt; wert = (_quote &gt;&gt; _txtmatch_quote[&amp;this-&gt;addValue()] &gt;&gt; _quote);
rule&lt;&gt; wert = (_quote &gt;&gt; _txtmatch_quote[&amp;this-&gt;addValue&lt;iterator_t&gt;] &gt;&gt; _quote);
rule&lt;&gt; wert = (_quote &gt;&gt; _txtmatch_quote[&amp;this-&gt;addValue] &gt;&gt; _quote);
rule&lt;&gt; wert = (_quote &gt;&gt; _txtmatch_quote[boost::bind&lt;void&gt;(&amp;bibliography::addValue, this,_1, _2)] &gt;&gt; _quote);

usw.
</code></pre>
<p>Ich bekomme immer nur die verücktesten Fehlermeldungen. Also, wenn einer vielleicht eine Idee hat... Es ist zum Haaaareraufen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/topic/198885/wie-kann-ich-boost-spirit-mit-meiner-callback-funktion-füttern</link><generator>RSS for Node</generator><lastBuildDate>Fri, 02 Oct 2026 20:01:50 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/198885.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 26 Nov 2007 18:08:47 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Wie kann ich Boost::Spirit mit meiner Callback-Funktion füttern? on Mon, 26 Nov 2007 18:10:35 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>Ich habe mir mit Boost::Spirit einen Parser für BibTex-Dateien geschrieben, der im Prinzip bereits funktioniert. Nun möchte ich das gute Stück aber in eine Klasse verpacken, welche mir eine BibTex-Datei verwaltet. Dabei werden die Callback-Funktionen zum Problem.<br />
Bis jetzt ging es so:</p>
<pre><code>std::string stack;
rule&lt;&gt; rule_wert = (rule_quote &gt;&gt; rule_txtmatch_quote [out&lt;const char*&gt;(stack)] &gt;&gt; rule_quote)
</code></pre>
<p>Dabei war out&lt;typename itT&gt;() ein Funktor, welcher dafür sorgt, dass Ausdrücke, die auf rule_txtmatch_quote passen im string Stack gespeichert werden.<br />
Jetzt habe ich aber den Parser und die Callback-Funktionen als Methoden in meine BibTex-klasse gepackt. Die Callback Funktion soll die geparsten Ausdrücke in einem Containerobjekt ablegen. Das soll in etwa so aussehen:</p>
<pre><code>class bibliography{

   ...

private:
   row _columns;
   std::vector&lt;row&gt; _rows;

   template&lt;typename iterator_t&gt;
   void addValue(file_iterator begin, file_iterator end);

   ...

   template&lt;typename iterator_t&gt;
   bool parse(iterator_t begin, iterator_t end);
}
</code></pre>
<p>Aber wie kann ich jetzt innerhalb meiner parse()-Funktion die Funktion addValue() übergeben. Ich habe zahlreiche Varianten versucht:</p>
<pre><code>rule&lt;&gt; wert = (_quote &gt;&gt; _txtmatch_quote[&amp;this-&gt;addValue()] &gt;&gt; _quote);
rule&lt;&gt; wert = (_quote &gt;&gt; _txtmatch_quote[&amp;this-&gt;addValue&lt;iterator_t&gt;] &gt;&gt; _quote);
rule&lt;&gt; wert = (_quote &gt;&gt; _txtmatch_quote[&amp;this-&gt;addValue] &gt;&gt; _quote);
rule&lt;&gt; wert = (_quote &gt;&gt; _txtmatch_quote[boost::bind&lt;void&gt;(&amp;bibliography::addValue, this,_1, _2)] &gt;&gt; _quote);

usw.
</code></pre>
<p>Ich bekomme immer nur die verücktesten Fehlermeldungen. Also, wenn einer vielleicht eine Idee hat... Es ist zum Haaaareraufen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1410518</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1410518</guid><dc:creator><![CDATA[Wirdbald]]></dc:creator><pubDate>Mon, 26 Nov 2007 18:10:35 GMT</pubDate></item><item><title><![CDATA[Reply to Wie kann ich Boost::Spirit mit meiner Callback-Funktion füttern? on Mon, 26 Nov 2007 18:44:12 GMT]]></title><description><![CDATA[<p>mem_fn_ptr oder so heißt die Funktion ... in Kombination mit bind ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1410536</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1410536</guid><dc:creator><![CDATA[*D*Evil]]></dc:creator><pubDate>Mon, 26 Nov 2007 18:44:12 GMT</pubDate></item><item><title><![CDATA[Reply to Wie kann ich Boost::Spirit mit meiner Callback-Funktion füttern? on Mon, 26 Nov 2007 19:11:22 GMT]]></title><description><![CDATA[<p>Hm, so ähnlich vielleicht:</p>
<pre><code>rule&lt;&gt; rule_wert = (rule_quote &gt;&gt; rule_txtmatch_quote [boost::mem_fn&lt;void, bibliography&gt;((bibliography::addValue&lt;iterator_t&gt;) (iterator_t A1, iterator_t A2))] &gt;&gt; rule_quote);
</code></pre>
<p>Das führt leider zu &quot;D:\programmierung\aktuell\bibtexparser\bibtex.hpp|163|error: expected primary-expression before &quot;A1&quot;|&quot; obwohl iterator_t eigentlich bekannt sein müsste <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":-("
      alt="😞"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1410553</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1410553</guid><dc:creator><![CDATA[Wirdbald]]></dc:creator><pubDate>Mon, 26 Nov 2007 19:11:22 GMT</pubDate></item><item><title><![CDATA[Reply to Wie kann ich Boost::Spirit mit meiner Callback-Funktion füttern? on Mon, 26 Nov 2007 19:12:34 GMT]]></title><description><![CDATA[<p>Das Problem ist dass addValue ein Template ist.<br />
In so einem Fall muss man sich den Funktor schon selbst schreiben, sonst wird das nicht funktionieren.</p>
<pre><code class="language-cpp">struct BibliographyAddValue
{
    BibliographyAddValue(bibliography* bib) :
        m_bib(bib)
    {
    }

    template&lt;typename iterator_t&gt; void operator() (iterator_t begin, iterator_t end) const
    {
        m_bib-&gt;addValue(begin, end);
    }

    bibliography* m_bib;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1410555</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1410555</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 26 Nov 2007 19:12:34 GMT</pubDate></item><item><title><![CDATA[Reply to Wie kann ich Boost::Spirit mit meiner Callback-Funktion füttern? on Tue, 27 Nov 2007 07:00:30 GMT]]></title><description><![CDATA[<p>Hm, ok. Vielen Dank schonmal.</p>
<p>Leider klappt auch das nicht. So bekomme ich ein Problem mit der include-Reihenfolge. Für das bibliography-Objekt will der Compiler den Funktor schon kennen und umgekehrt. Da helfen auch säuberliche Includes + Include-Guard nicht. Und die Definition der Funktionen kann ich auch nicht aus den Headern rausnehmen, weil es ja alles Templates sind.<br />
...<br />
Also entweder ich verzichte auf Templates oder auf Objekte. So macht das echt kein Spaß.</p>
<p>So habe ich das provisorisch versucht:</p>
<pre><code class="language-cpp">// struct.hpp

#ifndef STRUCT_HPP
#define STRUCT_HPP

#include &quot;bibtex.hpp&quot;

namespace bibtex{

   enum typ_enum{ROW,KEY,FIELD,VALUE,STRING,COMMENT};

   struct out
   {
      out(bibliography* bib) : _bib(bib)
      { }

      template&lt;typename itT, typ_enum typ&gt;
      void operator()(itT begin, itT end) const
      {
         switch(typ)
         {
            case ROW:
               _bib-&gt;newRow&lt;itT&gt;(begin, end);
               break;
            case KEY:
               _bib-&gt;addKey&lt;itT&gt;(begin, end);
               break;
            case FIELD:
               _bib-&gt;addField&lt;itT&gt;(begin, end);
               break;
            case VALUE:
               _bib-&gt;addValue&lt;itT&gt;(begin, end);
               break;
            case STRING:
               _bib-&gt;addString&lt;itT&gt;(begin, end);
               break;
            case COMMENT:
               _bib-&gt;addComment&lt;itT&gt;(begin, end);
               break;
         }
      }

      bibliography* _bib;

   };
}// namespace bibtex
</code></pre>
<p>Und:</p>
<pre><code class="language-cpp">//bibtex.hpp

#ifndef BIBTEX_HPP
#define BIBTEX_HPP
...

#include &quot;struct.hpp&quot;

namespace bibtex{

   class bibliography{

   public:
         ...
         template&lt;typename iterator_t&gt;
         bool parse(iterator_t begin, iterator_t end);

         //Hilfsfunktionen fürs Parsen
         template&lt;typename iterator_t&gt;
         void newRow(iterator_t begin, iterator_t end) const;
         template&lt;typename iterator_t&gt;
         void addKey(iterator_t begin, iterator_t end) const;
         ...
   };// class bibliography

   template&lt;typename iterator_t&gt;
   bool bibliography::parse(iterator_t begin, iterator_t end)
   {
      ...
      boost::spirit::rule&lt;&gt; wert = _quote &gt;&gt; _txtmatch_quote[out&lt;const char*,VALUE&gt;(this)] &gt;&gt; _quote;
      ...
   }

}//namespace bibtex
</code></pre>
<p>Ergebnis: Bei dieser Variante kommt jetzt das heraus:<br />
D:\programmierung\aktuell\bibtexparser\struct.hpp|17|error: expected <code>)' before '*' token D:\\programmierung\\aktuell\\bibtexparser\\struct.hpp|46|error: ISO C++ forbids declaration of</code>bibliography' with no type<br />
D:\programmierung\aktuell\bibtexparser\struct.hpp|46|error: expected `;' before '*' token</p>
<p>Zeile 17 ist diejenige, wo der Konstruktor von struct anfängt. Der Compiler mag also (bibliography* bib) nicht. Zeile 46 ist im obigen Code Zeile 43, also die mit &quot;bibliography* _bib;&quot;..</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1410708</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1410708</guid><dc:creator><![CDATA[Wirdbald]]></dc:creator><pubDate>Tue, 27 Nov 2007 07:00:30 GMT</pubDate></item><item><title><![CDATA[Reply to Wie kann ich Boost::Spirit mit meiner Callback-Funktion füttern? on Tue, 27 Nov 2007 10:53:11 GMT]]></title><description><![CDATA[<p>Du hast jetzt eine Cross-Referenz vorliegen, dh. die beiden Header-Dateien binden sich gegenseitig ein und das geht nicht.</p>
<p>Da du alles in Header-Dateien (wegen der Templates) implementieren mußt, hilft dir wohl nichts anderes, als eine Header-Datei zu machen und darin dann erst beide Klassen zu definieren und danach dann die Templatemethoden...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1410867</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1410867</guid><dc:creator><![CDATA[Th]]></dc:creator><pubDate>Tue, 27 Nov 2007 10:53:11 GMT</pubDate></item><item><title><![CDATA[Reply to Wie kann ich Boost::Spirit mit meiner Callback-Funktion füttern? on Tue, 27 Nov 2007 10:57:24 GMT]]></title><description><![CDATA[<p>Statt boost::bind musst du in spirit afaik phoenix::bind benutzen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1410871</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1410871</guid><dc:creator><![CDATA[phlox81]]></dc:creator><pubDate>Tue, 27 Nov 2007 10:57:24 GMT</pubDate></item><item><title><![CDATA[Reply to Wie kann ich Boost::Spirit mit meiner Callback-Funktion füttern? on Tue, 27 Nov 2007 13:41:39 GMT]]></title><description><![CDATA[<p>Ok, nächster Versuch:</p>
<pre><code class="language-cpp">namespace bibtex{

   enum typ_enum{ROW,KEY,FIELD,VALUE,STRING,COMMENT};

   template &lt;typename target_type, typ_enum typ&gt; struct out
   {
      out(target_type* t) : _target(t) {}

      template&lt;typename itT&gt; void operator()(itT begin, itT end) const
      {
         // wäre &quot;schöner&quot; über spezialisierung zu lösen, aber der Einfachheit halber lasse ich es mal mit switch(typ)
         switch(typ)
         {
            case ROW: _target-&gt;newRow&lt;itT&gt;(begin, end); break;
            case KEY: _target-&gt;addKey&lt;itT&gt;(begin, end); break;
            case FIELD: _target-&gt;addField&lt;itT&gt;(begin, end); break;
            case VALUE: _target-&gt;addValue&lt;itT&gt;(begin, end); break;
            case STRING: _target-&gt;addString&lt;itT&gt;(begin, end); break;
            case COMMENT: _target-&gt;addComment&lt;itT&gt;(begin, end); break;
            default: terminate();
         }
      }

      target_type* _target;
   };
}// namespace bibtex
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1410989</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1410989</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 27 Nov 2007 13:41:39 GMT</pubDate></item><item><title><![CDATA[Reply to Wie kann ich Boost::Spirit mit meiner Callback-Funktion füttern? on Tue, 27 Nov 2007 14:16:01 GMT]]></title><description><![CDATA[<p>Nicht schlecht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /><br />
Das war auch gleich die erste Idee, die ich dann hatte. Also so:</p>
<pre><code class="language-cpp">#ifndef STRUCT_HPP
#define STRUCT_HPP

#include &quot;bibtex.hpp&quot;

namespace bibtex{

   enum typ_enum{ROW,KEY,FIELD,VALUE,STRING,COMMENT};

   template&lt;typename target_type, typ_enum typ&gt;
   struct out
   {
      out(target_type* bib) : _bib(bib)
      { }

      template&lt;typename itT&gt;
      void operator()(itT begin, itT end) const
      {
         switch(typ)
         {
            case ROW:
               _bib-&gt;newRow&lt;itT&gt;(begin, end);
               break;
            case KEY:
               _bib-&gt;addKey&lt;itT&gt;(begin, end);
               break;
            case FIELD:
               _bib-&gt;addField&lt;itT&gt;(begin, end);
               break;
            case VALUE:
               _bib-&gt;addValue&lt;itT&gt;(begin, end);
               break;
            case STRING:
               _bib-&gt;addString&lt;itT&gt;(begin, end);
               break;
            case COMMENT:
               _bib-&gt;addComment&lt;itT&gt;(begin, end);
               break;
         }
      }

      target_type* _bib;
   };
}// namespace bibtex
#endif
</code></pre>
<p>Aber selbstverständlich geht auch das nicht. Dann sagt mein schnuckeliger gcc (diesmal stimmen die Zeilennummern):</p>
<pre><code>D:\programmierung\aktuell\bibtexparser\struct.hpp||In member function `void bibtex::out&lt;target_type, typ&gt;::operator()(itT, itT) const':|
D:\programmierung\aktuell\bibtexparser\struct.hpp|23|error: expected primary-expression before '&gt;' token|
D:\programmierung\aktuell\bibtexparser\struct.hpp|26|error: expected primary-expression before '&gt;' token|
D:\programmierung\aktuell\bibtexparser\struct.hpp|29|error: expected primary-expression before '&gt;' token
...
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1411030</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1411030</guid><dc:creator><![CDATA[Wirdbald]]></dc:creator><pubDate>Tue, 27 Nov 2007 14:16:01 GMT</pubDate></item><item><title><![CDATA[Reply to Wie kann ich Boost::Spirit mit meiner Callback-Funktion füttern? on Tue, 27 Nov 2007 23:19:49 GMT]]></title><description><![CDATA[<p>Ich denke ich habe ein 'template' Keyword vergessen (MSVC ist da (leider) nicht so streng <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /> ):</p>
<pre><code class="language-cpp">//_bib-&gt;newRow&lt;itT&gt;(begin, end); 
// -&gt;
_bib-&gt;template newRow&lt;itT&gt;(begin, end);
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1411331</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1411331</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 27 Nov 2007 23:19:49 GMT</pubDate></item><item><title><![CDATA[Reply to Wie kann ich Boost::Spirit mit meiner Callback-Funktion füttern? on Wed, 28 Nov 2007 20:03:53 GMT]]></title><description><![CDATA[<p>Problem gelöst: Das war nur eine triviale Kleinigkeit. Aber bei den Fehlermeldungen, die der Compiler ausschmeißt, sobald Boost im Spiel ist, denkt man ja man hätte weiß Gott was falsch gemacht. Vielen Dank jedenfalls für Eure Geduld.</p>
<p>Für die Nachwelt:<br />
Der Fehler lag darin, dass ich den Callback Funktionen den falschen Parametertyp gegeben habe. Boost::Spirit wollte Funktionen, die nicht denselben Iterator neben, wie der Parser, sondern welche vom Typ const char*.<br />
Es klappt problemlos, mit boost::bind() Klassenfunktionen zu übergeben, sogar wenn das Templates sind. Schöne Sache! Hier mal Auschnitte aus dem Code, der sich nicht nur Kompilieren lässt, sondern auch läuft:</p>
<pre><code class="language-cpp">// bibtex.hpp
namespace bibtex{

   class bibliography{
      ...

      private:
      ...

         //Die Parser-Funktion
         bool parse(std::string::iterator begin, std::string::iterator end);

         //Hilfsfunktionen fürs Parsen

         template&lt;typename itT&gt;
         void newRow(itT begin, itT end) const;

         void addKey(const char* begin, const char* end) const;
         ...

   };// class bibliograph

}// namespace bibtex
</code></pre>
<pre><code class="language-cpp">// bibtex.cpp
namespace bibtex{
      template&lt;typename itT&gt;
      void bibliography::newRow(itT begin, itT end) const
      {
         //noch leer
      }
      void bibliography::addKey(const char* begin, const char* end) const 
      {
         //noch leer
      }
      bool bibliography::parse(std::string::iterator begin, std::string::iterator end)
      {
         ...
         //Hier wird die template-funktion aufgerufen
            boost::spirit::rule&lt;&gt; blocktyp    = (* (_txtcore-space_p) )[bind(&amp;bibliography::newRow&lt;const char*&gt;, this,_1, _2)];

         //Hier die andere
            boost::spirit::rule&lt;&gt; blockkey    = (* (_txtcore-space_p) )[bind(&amp;bibliography::addKey, this,_1, _2)];
         ...
      }

}// namespace bibtex
</code></pre>
<p>Netterweise beschwert sich gcc jetzt noch nicht einmal darüber, dass ich die template-funktion erst in der Quelltextdatei definiert habe. Wahrscheinlich, weil ich sie auch nur dort brauche. Bei einer private-Methode ist das ja erstmal unproblematisch.</p>
<p>Vielleicht hilft das ja nochmal jemandem <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1411854</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1411854</guid><dc:creator><![CDATA[Wirdbald]]></dc:creator><pubDate>Wed, 28 Nov 2007 20:03:53 GMT</pubDate></item></channel></rss>