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