Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing a boost::fusion::map in boost::spirit::karma
    text
    copied!<p>I am using boost spirit to parse some text files into a data structure and now I am beginning to generate text from this data structure (using spirit karma).</p> <p>One attempt at a data structure is a boost::fusion::map (as suggested in an answer to <a href="https://stackoverflow.com/questions/409827/boosttuples-vs-structs-for-return-values">this</a> question). But although I can use boost::spirit::qi::parse() and get data in it easily, when I tried to generate text from it using karma, I failed.</p> <p>Below is my attempt (look especially at the "map_data" type). After some reading and playing around with other fusion types, I found boost::fusion::vector and BOOST_FUSION_DEFINE_ASSOC_STRUCT. I succeeded to generate output with both of them, but they don't seem ideal: in vector you cannot access a member using a name (it is like a tuple) -- and in the other solution, I don't think I need both ways (member name and key type) to access the members. </p> <pre><code>#include &lt;iostream&gt; #include &lt;string&gt; #include &lt;boost/spirit/include/karma.hpp&gt; #include &lt;boost/fusion/include/map.hpp&gt; #include &lt;boost/fusion/include/make_map.hpp&gt; #include &lt;boost/fusion/include/vector.hpp&gt; #include &lt;boost/fusion/include/as_vector.hpp&gt; #include &lt;boost/fusion/include/transform.hpp&gt; struct sb_key; struct id_key; using boost::fusion::pair; typedef boost::fusion::map &lt; pair&lt;sb_key, int&gt; , pair&lt;id_key, unsigned long&gt; &gt; map_data; typedef boost::fusion::vector &lt; int, unsigned long &gt; vector_data; #include &lt;boost/fusion/include/define_assoc_struct.hpp&gt; BOOST_FUSION_DEFINE_ASSOC_STRUCT( (), assocstruct_data, (int, a, sb_key) (unsigned long, b, id_key)) namespace karma = boost::spirit::karma; template &lt;typename X&gt; std::string to_string ( const X&amp; data ) { std::string generated; std::back_insert_iterator&lt;std::string&gt; sink(generated); karma::generate_delimited ( sink, karma::int_ &lt;&lt; karma::ulong_, karma::space, data ); return generated; } int main() { map_data d1(boost::fusion::make_map&lt;sb_key, id_key&gt;(234, 35314988526ul)); vector_data d2(boost::fusion::make_vector(234, 35314988526ul)); assocstruct_data d3(234,35314988526ul); std::cout &lt;&lt; "map_data as_vector: " &lt;&lt; boost::fusion::as_vector(d1) &lt;&lt; std::endl; //std::cout &lt;&lt; "map_data to_string: " &lt;&lt; to_string(d1) &lt;&lt; std::endl; //*FAIL No 1* std::cout &lt;&lt; "at_key (sb_key): " &lt;&lt; boost::fusion::at_key&lt;sb_key&gt;(d1) &lt;&lt; boost::fusion::at_c&lt;0&gt;(d1) &lt;&lt; std::endl &lt;&lt; std::endl; std::cout &lt;&lt; "vector_data: " &lt;&lt; d2 &lt;&lt; std::endl; std::cout &lt;&lt; "vector_data to_string: " &lt;&lt; to_string(d2) &lt;&lt; std::endl &lt;&lt; std::endl; std::cout &lt;&lt; "assoc_struct as_vector: " &lt;&lt; boost::fusion::as_vector(d3) &lt;&lt; std::endl; std::cout &lt;&lt; "assoc_struct to_string: " &lt;&lt; to_string(d3) &lt;&lt; std::endl; std::cout &lt;&lt; "at_key (sb_key): " &lt;&lt; boost::fusion::at_key&lt;sb_key&gt;(d3) &lt;&lt; d3.a &lt;&lt; boost::fusion::at_c&lt;0&gt;(d3) &lt;&lt; std::endl; return 0; } </code></pre> <p>Including the commented line gives lots of pages of compilation errors, among which notably something like: no known conversion for argument 1 from ‘boost::fusion::pair’ to ‘double’ no known conversion for argument 1 from ‘boost::fusion::pair’ to ‘float’</p> <p>Might it be that to_string needs the values of the map_data, and not the pairs? Though I am not good with templates, I tried to get a vector from a map using transform in the following way</p> <pre><code>template &lt;typename P&gt; struct take_second { typename P::second_type operator() (P p) { return p.second; } }; // ... inside main() pair &lt;char, int&gt; ff(32); std::cout &lt;&lt; "take_second (expect 32): " &lt;&lt; take_second&lt;pair&lt;char,int&gt;&gt;()(ff) &lt;&lt; std::endl; std::cout &lt;&lt; "transform map_data and to_string: " &lt;&lt; to_string(boost::fusion::transform(d1, take_second&lt;&gt;())); //*FAIL No 2* </code></pre> <p>But I don't know what types am I supposed to give when instantiating take_second and anyway I think there must be an easier way to get (iterate over) the values of a map (is there?)</p> <p>If you answer this question, please also give your opinion on whether using an ASSOC_STRUCT or a map is better.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload