Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use boost::lexical_cast and std::boolalpha? i.e. boost::lexical_cast< bool >("true")

Tags:

I've seen some answers to other boost::lexical_cast questions that assert the following is possible:

bool b = boost::lexical_cast< bool >("true");

This doesn't work for me with g++ 4.4.3 boost 1.43. (Maybe it's true that it works on a platform where std::boolalpha is set by default)

This is a nice solution to the string to bool problem but it lacks input validation that boost::lexical_cast provides.

like image 665
poindexter Avatar asked Dec 15 '10 16:12

poindexter


2 Answers

I'm posting the answer to my own question here for others who may be looking for something like this:

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

usage:

#include <boost/lexical_cast.hpp>
#include <iostream>
#include "LocaleBool.hpp"

int main() {
    bool b = boost::lexical_cast< LocaleBool >("true");
    std::cout << std::boolalpha << b << std::endl;
    std::string txt = boost::lexical_cast< std::string >( LocaleBool( b ) );
    std::cout << txt << std::endl;
    return 0;
}
like image 180
poindexter Avatar answered Oct 06 '22 01:10

poindexter


In addition to the answer form poindexter, you can wrap the method from here in a specialized version of boost::lexical_cast:

namespace boost {
    template<> 
    bool lexical_cast<bool, std::string>(const std::string& arg) {
        std::istringstream ss(arg);
        bool b;
        ss >> std::boolalpha >> b;
        return b;
    }

    template<>
    std::string lexical_cast<std::string, bool>(const bool& b) {
        std::ostringstream ss;
        ss << std::boolalpha << b;
        return ss.str();
    }
}

And use it:

#include <iostream>
#include <boost/lexical_cast.hpp>

//... specializations

int main() {
    bool b = boost::lexical_cast<bool>(std::string("true"));
    std::cout << std::boolalpha << b << std::endl;
    std::string txt = boost::lexical_cast< std::string >(b);
    std::cout << txt << std::endl;

    return 0;
}

I personally liked this approach because it hides any special code (e.g. using LocaleBool or to_bool(...) from the link) for converting to/from bools.

like image 22
womple Avatar answered Oct 06 '22 02:10

womple