I'm trying to parse JSON using Boost's property_tree parser and from C++11 code (my system is Debian Wheezy with gcc 4.7.2 and Boost 1.49). I tried the following code based on Serializing and deserializing json with boost:
#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");
}
If I compile this with 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' I get compile errors:
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> > >&}’
How can I use Boost's read_json with C++11? Do I need a newer Boost version for this (i. e. install manually from source instead of using Wheezy's packaged one)? Is there something wrong in my code? Or is this simply not possible?
It is a known bug of older Boost versions.
You can fix it by applying the following 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();
}
or with
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
来源:https://stackoverflow.com/questions/18552427/boost-read-json-and-c11