2013-08-31 15 views
8

Sto cercando di analizzare JSON utilizzando il parser property_tree di Boost e il codice C++ 11 (il mio sistema è Debian Wheezy con gcc 4.7.2 e Boost 1.49). Ho provato il seguente codice in base a Serializing and deserializing json with boost:Boost read_json e C++ 11

#include <map> 
#include <sstream> 
#include <boost/property_tree/ptree.hpp> 
#include <boost/property_tree/json_parser.hpp> 
using boost::property_tree::ptree; using boost::property_tree::read_json; using boost::property_tree::write_json; 

void example() { 
    // Write json. 
    ptree pt; 
    pt.put ("foo", "bar"); 
    std::ostringstream buf; 
    write_json (buf, pt, false); 
    std::string json = buf.str(); // {"foo":"bar"} 

    // Read json. 
    ptree pt2; 
    std::istringstream is (json); 
    read_json (is, pt2); 
    std::string foo = pt2.get<std::string> ("foo"); 
} 

Se compilo questo con g++ -std=c++03 -c' everything is fine. However, I also want to use C++11 features (which the code in the linked thread actually does!). But with g ++ -std = C++ 11 -c' ricevo errori di compilazione:

In file included from /usr/include/boost/property_tree/json_parser.hpp:14:0, 
       from test.cpp:4: 
/usr/include/boost/property_tree/detail/json_parser_read.hpp: In instantiation of ‘void boost::property_tree::json_parser::context<Ptree>::a_literal_val::operator() (boost::property_tree::json_parser::context<Ptree>::It,  boost::property_tree::json_parser::context<Ptree>::It) const [with Ptree = boost::property_tree::basic_ptree<std::basic_string<char>, std::basic_string<char> >; boost::property_tree::json_parser::context<Ptree>::It = __gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >]’: 
/usr/include/boost/spirit/home/classic/core/scanner/scanner.hpp:148:13: required from ‘static void boost::spirit::classic::attributed_action_policy<boost::spirit::classic::nil_t>::call(const ActorT&, boost::spirit::classic::nil_t, const IteratorT&, const IteratorT&) [with ActorT = boost::property_tree::json_parser::context<boost::property_tree::basic_ptree<std::basic_string<char>, std::basic_string<char> > >::a_literal_val; IteratorT = __gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >]’ 
/usr/include/boost/spirit/home/classic/core/scanner/scanner.hpp:163:13: required from ‘void boost::spirit::classic::action_policy::do_action(const ActorT&, AttrT&, const IteratorT&, const IteratorT&) const [with ActorT = boost::property_tree::json_parser::context<boost::property_tree::basic_ptree<std::basic_string<char>, std::basic_string<char> > >::a_literal_val; AttrT = boost::spirit::classic::nil_t; IteratorT = __gnu_cxx::__normal_iterator<char*, std::vector<char, std::allocator<char> > >]’ 
... 
test.cpp:20:1: required from here 
/usr/include/boost/property_tree/detail/json_parser_read.hpp:105:17: error: no matching function for call to ‘boost::property_tree::basic_ptree<std::basic_string<char>, std::basic_string<char> >::push_back(std::pair<std::basic_string<char>, std::basic_string<char> >)’ 
/usr/include/boost/property_tree/detail/json_parser_read.hpp:105:17: note: candidate is: 
In file included from /usr/include/boost/property_tree/ptree.hpp:516:0, 
      from test.cpp:3: 
/usr/include/boost/property_tree/detail/ptree_implementation.hpp:362:9: note: boost::property_tree::basic_ptree<Key, Data, KeyCompare>::iterator boost::property_tree::basic_ptree<Key, Data, KeyCompare>::push_back(const value_type&) [with Key = std::basic_string<char>; Data = std::basic_string<char>; KeyCompare = std::less<std::basic_string<char> >; boost::property_tree::basic_ptree<Key, Data, KeyCompare>::value_type = std::pair<const std::basic_string<char>, boost::property_tree::basic_ptree<std::basic_string<char>, std::basic_string<char> > >] 
/usr/include/boost/property_tree/detail/ptree_implementation.hpp:362:9: note: no known conversion for argument 1 from ‘std::pair<std::basic_string<char>, std::basic_string<char> >’ to ‘const value_type& {aka const std::pair<const std::basic_string<char>, boost::property_tree::basic_ptree<std::basic_string<char>, std::basic_string<char> > >&}’ 

Come posso usare Boost read_json con C++ 11? Ho bisogno di una versione Boost più recente per questo (vale a dire installare manualmente dal sorgente invece di utilizzare quello confezionato di Wheezy)? C'è qualcosa di sbagliato nel mio codice? O semplicemente non è possibile?

risposta

8

È un known bug di versioni Boost precedenti.
È possibile risolvere il problema applicando la seguente patch:

--- json_parser_read.hpp  2013-09-01 03:55:57.000000000 +0400 
+++ /usr/include/boost/property_tree/detail/json_parser_read.hpp  2013-09-01 03:56:21.000000000 +0400 
@@ -102,7 +102,7 @@ 
      void operator()(It b, It e) const 
      { 
       BOOST_ASSERT(c.stack.size() >= 1); 
-    c.stack.back()->push_back(std::make_pair(c.name, Str(b, e))); 
+    c.stack.back()->push_back(std::make_pair(c.name, Ptree(Str(b, e)))); 
       c.name.clear(); 
       c.string.clear(); 
      } 

o con

sed -i -e 's/std::make_pair(c.name, Str(b, e))/std::make_pair(c.name, Ptree(Str(b, e)))/' json_parser_read.hpp 
+0

Grazie, questo cancella il problema per me completamente. :) –