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)?
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());
}