c++boostlexical-castfolly

How can I use boost::lexical_cast with folly::fbstring?


The following program:

#include <boost/container/string.hpp>
#include <boost/lexical_cast.hpp>
#include <folly/FBString.h>
#include <iostream>

class foo { };

std::ostream& operator<<(std::ostream& stream, const foo&) {
  return stream << "hello world!\n";
}

int main() {
  std::cout << boost::lexical_cast<std::string>(foo{});
  std::cout << boost::lexical_cast<boost::container::string>(foo{});
  std::cout << boost::lexical_cast<folly::fbstring>(foo{});
  return 0;
}

gives this output:

hello world!
hello world!
terminate called after throwing an instance of 'boost::bad_lexical_cast'
  what():  bad lexical cast: source type value could not be interpreted as target

This is because lexical_cast doesn't realise that fbstring is a string-like type, and simply does it's usual stream << in; stream >> out; for the conversion. But operator>> for strings stops at the first whitespace, lexical_cast detects that the whole input was not consumed, and throws an exception.

Is there any way to teach lexical_cast about fbstring (or, more generally, any string-like type)?


Solution

  • From looking at the lexical_cast documentation it appears that std::string is explicitly the only string-like exception allowed to normal lexical-cast semantics, to keep the meaning of the cast as straightforward as possible and catch as many possible conversion errors as can be caught. The documentation also says that for other cases to use alternatives such as std::stringstream.

    In your case I think a to_fbstring method would be perfect:

    template <typename T>
    fbstring to_fbstring(const T& item)
    {
        std::ostringstream os;
    
        os << item;
    
        return fbstring(os.str());
    }