c++ - why does a constant string become a bool when used for input to variant<bool, std::string>? -


i have condensed problem (maybe not smallest) sample application below. sample generic json parser. however, exhibits 2 issues. 1. when none of other options pass, outputs true or false when bool_ outputter in variant list. if isn't last one, after unused. can't figure out why. 2. when input string, string handler never fired variant. when used outside variant, fires.

the example code has string output simplified karma::string , still exhibits error. when take learned here , return real application, string output c style escaped string, works karma::string not help.

i have read (and reread) output of boost::variant type using boost::spirit::karma , boost::spirit::karma output of string in quotation marks , either can't apply case (ie don't understand answer after all) or else doesn't work in more complex example. , familiar mini_xml example code.

any suggestions doing wrong? , why doing wrong , fix right?

all appreciated.

#include <boost/variant/recursive_variant.hpp> #include <string> #include <vector>  namespace lloyd { namespace json {  struct null {     bool operator==(const null& cmp) {return true; } };  struct element;  typedef boost::make_recursive_variant<null, bool, long, double, std::string, std::vector<element>, std::vector<boost::recursive_variant_> >::type value;  struct element {     std::string name;     json::value value;     inline element(const element& src): name(src.name), value(src.value) {}     inline element(const std::string& name, const json::value& value): name(name), value(value) {}     inline element() {} };  typedef std::vector<element> object;  } }  #include <boost/fusion/adapted.hpp>  boost_fusion_adapt_struct(     lloyd::json::element,     (std::string, name)     (lloyd::json::value, value) )  #include <boost/spirit/include/karma.hpp> #include <boost/spirit/include/karma_auto.hpp>  #include <boost/spirit/include/phoenix.hpp>  namespace lloyd { namespace json { namespace karma {  template <typename outputiterator> struct json_object_out_generator     : boost::spirit::karma::grammar<outputiterator, json::object(bool, unsigned, unsigned) > {     //  json output grammars     boost::spirit::karma::rule<outputiterator, std::vector<json::value>(bool, unsigned, unsigned) > array_rule;     boost::spirit::karma::rule<outputiterator, json::null(bool, unsigned, unsigned) > null_rule;     boost::spirit::karma::rule<outputiterator, json::value(bool, unsigned, unsigned) > value_rule;     boost::spirit::karma::rule<outputiterator, json::element(bool, unsigned, unsigned) > elem_rule;     boost::spirit::karma::rule<outputiterator, json::object(bool, unsigned, unsigned) > obj_rule;      json_object_out_generator() : json_object_out_generator::base_type(obj_rule)     {         using boost::spirit::lit;         using boost::spirit::_r1;         using boost::spirit::_r2;         using boost::spirit::_r3;          namespace karma=boost::spirit::karma;          null_rule %= karma::eps << boost::spirit::karma::lit("null");         array_rule %= lit("[") << -(value_rule(_r1, _r2, _r3) % lit(",") ) << "]";         value_rule %= ( null_rule(_r1, _r2, _r3) | karma::string | karma::long_ | karma::double_ | obj_rule(_r1, _r2, _r3) | array_rule(_r1, _r2, _r3) | karma::bool_);         elem_rule %= boost::spirit::karma::string << ":" << -value_rule(_r1, _r2+1, _r3);         obj_rule %= boost::spirit::lit("{")             << -boost::spirit::buffer[( elem_rule(_r1, _r2+1, _r3)  % ',' ) ]             << "}";      } };  }}}  #include <vector> #include <sstream> #include <iomanip>  #include <boost/assign/list_of.hpp>  #include <boost/assign/std/vector.hpp> using namespace boost::assign;  int main(int argc, const char* argv[]) {     using lloyd::json::value;     using lloyd::json::element;     using lloyd::json::null;     lloyd::json::object obj;     lloyd::json::object sobj;     std::vector<value> t5;     t5 += null(), true, false, value("testing"), sobj;      obj += element("t1", null()), element("t2", true), element("t3", false);     obj += element("t4", "testing 4"), element("t5", t5), element("t6", sobj);     obj += element("nt0", (long)50), element("nt1", 50.5), element("nt2", 50.0);      std::stringstream s;     typedef boost::spirit::karma::ostream_iterator<char> out_itr;     out_itr so(s);      lloyd::json::karma::json_object_out_generator<out_itr> json_object_out;                 //  our grammar definition     boost::spirit::karma::generate(so, json_object_out(true, 0, 1), obj);     std::cout << "result:\n";     std::cout << s.str() << std::endl;     return 0; } 

edited change title cover actual problem displayed. edited fix upload miss on code sample.

as someone's comments state, missing headers missed removing references (they exist here) to, had removed usage of.

however, actual problem above c++ basic object conversion rules. in case soemone else runs this:

c provides direct conversion pointer type boolean. c++ adds std::string class. class provides constructor const char*.

direct conversions simpler class constructors, conversion preferred when either can used. because simpler, not considered ambiguous on conversion use. thus, though char* string intended, compiler did pointer boolean, causing output boolean.

the information given vexocide on freenode ##spirit chat channel.

so, force desired conversion, if std::string("string here") used instead of "string here", have worked. boost::spirit::karma had no bearing on actual problem, gigo issue.


Comments

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

jquery - Fancybox - apply a function to several elements -

An easy way to program an Android keyboard layout app -