Boost property tree issue when converting to Unicode
Asked Answered
C

1

6

Ok, first off I'm not a C++ developer by nature; I've managed to put some stuff together and it works fine, but I'm sure through the eyes of an expert it looks like garbage =)

So I have a freeware app that I've made which uses Property Tree from the Boost libraries. I developed the entire app (in VS2010) with the Use Multi-Byte Character Set setting. I decided it was time to go through and update the app to support Unicode as there are some folks with complex character sets that I'd like to better support.

I went through the tedious process of changing all the references and calls to use wide strings, all the necessary conversions. However, I'm completely stumped at one point, the only two compiler errors I have left.

They both come from stream_translator.hpp (/boost/property_tree/), lines 33 and 36 (as noted below):

template <typename Ch, typename Traits, typename E, typename Enabler = void>
struct customize_stream
{
    static void insert(std::basic_ostream<Ch, Traits>& s, const E& e) {
        s << e; //line 33
    }
    static void extract(std::basic_istream<Ch, Traits>& s, E& e) {
        s >> e; //line 36
        if(!s.eof()) {
            s >> std::ws;
        }
    }
};

The error at line 33 is:

Error   347 error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'const std::wstring' (or there is no acceptable conversion)   {...}\boost_1_49_0\boost\property_tree\stream_translator.hpp    33  1   

..and the error at line 36 is:

Error   233 error C2678: binary '>>' : no operator found which takes a left-hand operand of type 'std::basic_istream<_Elem,_Traits>' (or there is no acceptable conversion) {...}\boost_1_49_0\boost\property_tree\stream_translator.hpp    36  1

From what I've been able to walk backwards through, it's coming from within stream_translator.hpp ultimately beginning as a call to get a value [e.g. ptree.get("some.path", "default value here")]

I really have absolutely no idea how to resolve this issue and cannot seem to find anything online to help me understand what exactly the problem is. Any tips or info would be greatly appreciated.

EDIT

So I commented out everything relating to ptree until it would compile, then began adding them back in. It turns out I can call .get fine, it's get_child where the error @ line 36 pops up (haven't done the other project yet, where the wstring issue is).

To simplify things, here is the effective sequence of the calls, which are fine until get_child is called:

boost::property_tree::ptree pt; 
boost::property_tree::read_xml("Config.xml", pt);
int iAppSetting = pt.get("config.settings.AppSetting",1); //<- works fine
ptree ptt;
ptt = pt.get_child("config.Applications"); //<- adding this line causes the line 36 error
Christyna answered 13/5, 2012 at 0:48 Comment(2)
"They both come from stream_translator.hpp " No, they come from your code passing wstrings to Boost code. VS2010 will show a list of template instantiations. Follow it until you get to your code and post that.Trihedral
To be clear, I never intended to blame the Boost code, I knew it was my code somewhere. I was being lazy and hoping someone had an easy answer. I've done the work to find the exact point of failure (for one of the issues) and made the updates above. Note that the above code works without error when using Multi-Byte, only fails once switching to Unicode.Christyna
M
8

Guessing that your problem was the same I ran into... There are wide character versions of Boost.PropertyTree for unicode support.

For Config.xml that is setup like this:

<?xml version="1.0"?>
<Zoo>
    <Monkey>
        <Food>Bananas</Food>
    </Monkey>
</Zoo>

Use code similar to this to parse it:

// Load up the property tree for wide characters
boost::property_tree::wptree pt;
boost::property_tree::read_xml("Config.xml", pt);

// Iterate
BOOST_FOREACH(wptree::value_type const& v, pt.get_child(L"Zoo"))
{
    if( v.first == L"Monkey" )
    {
        wstring foodType = v.second.get<wstring>(L"Food");
    }
}
Moriyama answered 17/4, 2013 at 22:3 Comment(1)
I don't think this will work. read_xml ONLY accepts a ptree, not a wptree.Fluting

© 2022 - 2024 — McMap. All rights reserved.