Boost logo

Boost :

From: Jeff Garland (jeff_at_[hidden])
Date: 2006-05-02 23:10:27


Oleg Abrosimov wrote:
> Jeff Garland:
>>> // embedded in expression usage:
>>> double d = 2 + (double)from_string(“1”);
>> I think having a C-style cast is a no no. I assume:
>>
>> double d = 2 + static_cast<double>(from_string(“1”));
>>
>> would work as well?
>
> yes, your version would work as well, but is too verbose ;-)
> the function from_string returns proxy object with templated cast to T
> operator defined. the purpose of explicit cast in the code above is to
> invoke the right cast operator.

That's what I thought, but given c-style cast I wasn't entirely sure.

> but I don't share the "no no" opinion against C-style cast in general.
>...snip cast no-no details...
>
> now consider the code snippet again:
> double d = 2 + (double)from_string(“1”);
>
> 1) is it hard to understand what is going on here? from first glance?
> after explanation?

Yeah, well I'm always a bit unsure when the
'c-big-nasty-beat-it-with-a-hammer-cast' is used. I'm thinking I want
to read/run the code just in case from_string returns a pointer and the
compiler adds the pointer to 2 giving me some wacko result.

> 4) C-style casts won't disappear in any observable time because of
> interoperability with C.

Well, they especially won't disappear if folks who know better (that's
you) perpetuate them. Not very many C++ programmers fully understand
the implications of the c-cast (me included). In my experience casting
leads to more casting -- programmers that don't understand what they are
doing copy the bad code. It's like a fungus on a piece of code. Sure
you can abuse new style casts, but it takes more time. You have to
rethink why you are casting in the first place...

> to conclude, I understand reasons against C-style cast in C++ and
> actually I don't remember when I've used it last time, but in this
> particular case I can not see any application of these reasons. I
> believe that in the case of "(double)from_string(“1”);" construct these
> reasons are just wrong.
>
> fill free to correct me, if I miss something.

I really think if you really plan to produce something that goes to the
standard committee you ought to drop the C and stick to C++. Maybe I'm
wrong, but I'm betting alot of C++ folks will have the same reaction as me.

> I like the "(double)from_string(“1”)" construct because it clearly says
> what is going on, it can be directly translated to: get double from
> string "1".
> Attractive! Isn't it?

Nope.

Well I'm afraid that I see one serious problem with this idea that
lexical cast avoids -- ambiguity. The following code will not compile on
g++ 3.3.2 -- totally bogus implementations, but just to give you the idea:
//test.cpp
#include <iostream>

double
from_string(std::string s)
{
   static double d = 10.2;
   return d;
}

int
from_string(std::string s)
{
   static int i = 10;
   return i;
}

using namespace std;

int
main()
{

   double d = 2 + (double)from_string("10.2");
   std::cout << d << std::endl;
   return 0;

}

test.cpp:6: error: ambiguates old declaration `double from_string(...

Basically, you can't overload on return type. Lexical cast gets around
this for the obvious reasons. Anyway, I'm starting to wonder if this
idea is feasible at all -- am I missing something?

>> One thing I didn't see address in your proposal is how 'user defined types'
>> can be handled. So, for example, with lexical cast I can do this:
>>
>> using namespace boost::gregorian;
>> date d(2006,May, 1);
>> std::string ds = lexical_cast<std::string>(d);
>>
>> and this
>>
>> std::string ds("2006-May-01");
>> date d = lexical_cast<date>(ds);
>>
>> This works because date has a defined operator<< and operator>>. You would
>> need to show how this would be done in your proposal to really compete with
>> lexical cast. Also note that with updates to the date-time global facet, the
>> format of the date can be changed around, localized etc.
>
> Of cause, you are right! The library proposed is a simple wrapper around
> std::iostreams and C-library functions, mentioned in n1982 proposal. It
> means that all functionality of iostreams (including UDT to string and
> vice versa conversions) are allowed (and encouraged, of cause).
>
> with the library proposed one can rewrote your example in the following way:
>
> using namespace boost::gregorian;
> date d(2006,May, 1);
> std::string ds = string_from(d);
>
> and this
>
> std::string ds("2006-May-01");
> date d = from_string(ds);
>
> simple and symmetric.

Well, again, I'm not sure how you can make this work. The only way I
know how is to make from_string a template function...so this is
basically back to lexical cast, no?

Jeff


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