
From: "Preston A. Elder" <prez@neuromancy.net>
#include <boost/lexical_cast.hpp> #include <iostream>
struct my_type { int a; int b; };
template<typename C, typename T> std::basic_istream<C,T> &operator>>(std::basic_istream<C,T> &is, my_type &mt) { is >> mt.a >> mt.b; return is; }
int main() { std::string input = "1 2"; my_type mt; try { mt = boost::lexical_cast<my_type>(s); std::cout << "TEST 1: " << mt.a << " " << mt.b << std::endl; } catch (boost::bad_lexical_cast &) { std::cout << "TEST 1 FAILED" << std::endl; }
input = "3 4"; std::stringstream ss;
ss << s; ss >> mt >> std::ws; if (ss.eof()) std::cout << "TEST 2: " << mt.a << " " << mt.b << std::endl; else std::cout << "TEST 1 FAILED" << std::endl;
return 0; }
The output I get is: TEST 1 FAILED TEST 2: 3 4
"s" is used a couple of places in the code, where I assume "input" should be used instead (or it gives an error when compiling). Apart from that, I get the same result.
My investigation has shown that this occurs because boost::lexical_cast calls stream.unsetf(std::ios::skipws);
There was recently another whitespace-with-lexical_cast related question at Boost users list, where the poster preferred no whitespace stripping. To quote: --- Start quote --- From: "Yuval Ronen" <ronen_yuval@yahoo.com> To: <boost-users@lists.boost.org> Sent: Saturday, January 15, 2005 5:47 PM Subject: [Boost-users] Two issues with lexical_cast <snip>
2. lexical_cast ignores trailing whitespaces, but not leading whitespaces. Meaning that
int a = lexical_cast<int>("3 "); // three-space
will work and return 3, but
int a = lexical_cast<int>(" 3"); // space-three
will throw. Why? There's no rationale here. Both cases should be treated in the same manner, and IMHO, that manner should be throwing.
--- End quote --- So what should lexical_cast do; strip or not? Ladies and gentlemen, can we have your votes? ;)
My question is, why does it do this - as this specifically stops lexical_cast from working with complex types. So could this be an option, or completely disabled, or made an option (somehow) to lexical_cast?
Adding options to lexical_cast is difficult. It's meant to resemble regular casts, and any additional template- or function-arguments makes it no longer look like a cast.
I understand some logic to not skipping whitespace, however I believe its use is limited - especially since there is a specialization for std::string and std::wstring already which does not even use operator>>.
As a side note, yes, I could change my operator>>, however the sample operator>> above is typical for an operator>> for a complex class, almost always they assume that skipws is turned on, and don't bother checking.
Good point. I've cc'ed this reply to Kevlin Henney, as I don't think he's subscribed to the list. Regards, Terje