Boost logo

Boost :

From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2005-01-29 17:53:45


>From: "Preston A. Elder" <prez_at_[hidden]>

> #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_at_[hidden]>
To: <boost-users_at_[hidden]>
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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk