Boost logo

Boost :

From: Oleg Abrosimov (beholder_at_[hidden])
Date: 2006-05-03 05:37:22


Jeff Garland:
>
> 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.

Ok I see your point. It would be interesting though to make a polling on
c.l.c++.m on this question just to see the whole picture.

anyway, usage of C-style cast is not required.
for simple initialization one can do:
double d = from_string("10.2");

and if one has a real need to use it in a complex expression:
double d = 2 + static_cast<double>(from_string("10.2"));

or, better:

double d = from_string("10.2");
d += 2;

and if one wants to be very modern ;-) but doesn't concern about
symmetry in from_string/string_from usage :
double d = 2 + from_string<double>("10.2");

it could be supported in parallel with non-templated version. (see code
below)

> 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?

see below

>
>> 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?
>

no, try the following code:

#include <iostream>
#include <sstream>

struct fs_helper
{
     fs_helper(std::string const& s) :
         m_str(s) {}
     template <typename T>
         operator T() {
             std::stringstream ss(m_str);
             T t;
             ss >> t;
             return t;
         }

private :
     std::string m_str;
};

inline fs_helper from_string(std::string const& str)
{
     return fs_helper(str);
}

template <typename T>
inline T from_string(std::string const& str)
{
     return static_cast<T>(fs_helper(str));
}

int main()
{
    double d0 = from_string("10.2");
    double d = 2 + (double)from_string("10.2");
    double d2 = 4 + from_string<double>("10.2");
    std::cout << d0 << std::endl;
    std::cout << d << std::endl;
    std::cout << d2 << std::endl;
    return 0;
}

it perfectly works on VC7.1 at least.
and compiles by
Comeau C/C++ 4.3.3 (Aug 6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing. All rights reserved.
MODE:strict errors C++

In strict mode, with -tused, Compile succeeded.

Best,
Oleg Abrosimov.


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