1. ホーム
  2. c++

[解決済み] Unicode への変換時に発生する Boost プロパティツリーの問題

2022-02-08 23:26:37

質問

OK、まず私は元々C++の開発者ではありません。何とかいくつかのものを組み立ててうまく動作していますが、専門家の目から見るとゴミのように見えると思います =)。

そこで、Boost ライブラリの Property Tree を使用したフリーウェアのアプリを作りました。アプリ全体を(VS2010で)開発したのですが、このアプリは マルチバイト文字セット という設定があります。複雑な文字セットを持つ人々がいるので、Unicodeをサポートするようにアプリを更新する時期が来たと判断しました。

私は、すべての参照と呼び出しをワイド文字列を使用するように変更し、必要なすべての変換を行う面倒なプロセスを経ました。しかし、ある点で完全に行き詰ってしまった。唯一残っている2つのコンパイラーエラーだ。

どちらも stream_translator.hpp (/boost/property_tree/)の33行目と36行目です(後述します)。

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;
        }
    }
};

33行目のエラーは

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   

...そして、36行目のエラーは。

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

私が逆引きで調べたところでは、内側から来る stream_translator.hpp 最終的に値を取得するための呼び出しとして始まる [例:ptree.get("some.path", "default value here")].

この問題を解決する方法が全く分からず、また、この問題を解決するために 何か この問題が何であるかを理解するために、オンラインを利用することができます。 何かヒントや情報があれば、非常にありがたいのですが。

EDIT

そこで、コンパイルできるようになるまでptreeに関連するものをすべてコメントアウトし、その後、それらを再び追加し始めました。私は.getをうまく呼び出すことができることが判明した、それは36行目のエラーがポップアップするget_childである(wstring問題がある他のプロジェクトはまだやっていない)。

物事を単純化するために、以下は呼び出しの効果的なシーケンスで、get_child が呼び出されるまでは問題ありません。

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

解決方法は?

あなたの問題は、私が遭遇したのと同じだと推測しています... Boost.PropertyTreeには、ユニコードに対応したワイドキャラクターバージョンが存在します。

Config.xmlの場合は、このように設定されています。

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

このようなコードを使ってパースします。

// 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");
    }
}