
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