How do I use boost::lexical_cast and std::boolalpha? i.e. boost::lexical_cast< bool >(“true”)
boost::lexical_cast()関数は、あらゆる型間の変換を統一的に扱うもので、とても便利です。
しかし、lexical_castのように、"true"という文字列からbool型に変換しようとしても失敗します。内部的に使用されるstringstreamオブジェクトにboolalphaを設定できればいいのですが、そのようなフォーマット設定は、lexical_castではできないようになっています。
上記StackOverflowで、おもしろい回答が出ていたので紹介します。
#include <iostream> #include <boost/lexical_cast.hpp> struct LocaleBool { bool data; LocaleBool() {} LocaleBool(bool data) : data(data) {} operator bool() const { return data; } friend std::ostream& operator<<(std::ostream& out, LocaleBool b) { out << std::boolalpha << b.data; return out; } friend std::istream& operator>>(std::istream& in, LocaleBool& b) { in >> std::boolalpha >> b.data; return in; } }; int main() { bool b = boost::lexical_cast<LocaleBool>("true"); std::cout << std::boolalpha << b << std::endl; }
true
lexical_castで直接bool型に変換するのではなく、boolに変換可能なクラスを用意して、その入出力演算子にboolalphaを仕込むのです。
これは非常におもしろい方法だと思います。
このコードだと、LocaleBoolクラス内で設定したboolalphaが、入出力演算子を抜けたあとでも効いたままになってしまうので、Boost.IOStateSaverを使用して関数脱出時に、ストリームのフォーマットを戻すようにしましょう。
#include <iostream> #include <boost/io/ios_state.hpp> #include <boost/lexical_cast.hpp> struct LocaleBool { bool data; LocaleBool() {} LocaleBool(bool data) : data(data) {} operator bool() const { return data; } friend std::ostream& operator<<(std::ostream& out, LocaleBool b) { boost::io::ios_flags_saver ifs(out); out << std::boolalpha << b.data; return out; } friend std::istream& operator>>(std::istream& in, LocaleBool& b) { boost::io::ios_flags_saver ifs(in); in >> std::boolalpha >> b.data; return in; } }; int main() { bool b = boost::lexical_cast<LocaleBool>("true"); std::cout << std::boolalpha << b << std::endl; }