On Dec 29, 8:06 am, (e-mail address removed) (blargg) wrote: [snip]
Especially old-style casts. If an inexperienced C++
programmer feels he must cast, he should stick to
static_cast unless he knows for certain. Even then,
static_cast requires care when downcasting.
Actually, the beginning programmer should stick to
dynamic_cast whenever pointers or references are concerned.
(I have no real problems with C style casts otherwise, but
it's really a style issue.)
That must be because you know what you're doing so much better
than the rest of us ;-)
You mean that I'm consciously aware that I'm using a different
style of cast that the new casts.
I almost never use C-style casting, and whenever I see one it
gives me a creeping feeling that something fishy might take
place.
C-style, perhaps, but I'll bet you do write things like
MyClass( 42 ), where MyClass has a constructor which takes an
int. And that's a function style cast, which has exactly the
same behavior as a C-style cast. Given that, things like
double( 42 ) don't bother me either. And of course, if the type
name requires more than a single token, it becomes (long
double)( 42 ). Which, formally, is a C-style cast.
My point, of course, is that all of the code I've ever seen uses
things like MyClass( 42 ). And MyClass(), if there is a default
constructor, and MyClass( 1, 2, 3 ) if there is a constructor
taking three ints, etc. In practice, I think that most people
don't think of it as a "type conversion" (although that's what
the standard calls it); they think of it as explicitly creating
a temporary of the given type. Or at least, that's the way I
think of it. And double( 42 ) is also explicitly creating a
temporary of type double---it happens that double has a
constructor taking a single argument. And that I find it
difficult to accept double( 42 ), but reject
(long double)( 42 ), just on the grounds that it has an extra
set of parentheses. And of course, if you accept
(long double)( 42 ), then you really have to accept
(double)( 42 ).
I don't use things like (double)42, without what is being
converted in parentheses.
The never casts gives me more confidence in the code although
I would have preferred the restrictions to be even stronger
for static_cast.
Let's say that I'd prefer a few other types of casts, e.g.
checked_cast, etc.
One exception to this is the "constructor cast": int i =
int(4.7). I really would have loved it if this cast had been
as safe as a static_cast.
Unless pointers and references are involved, it *is* a
static_cast (with perhaps a const_cast thrown in).
The issue isn't simple, and I can understand your desire to make
such things stand out. The problem is that you can't, really.
MyClass( 4.7 ) is going to work, even if MyClass only has a
constructor which takes an int, and there's nothing you can do
about it. This is a serious flaw in the language, but one that,
for practical considerations of backwards compatibility, can't
really be fixed. (There was once a proposal to deprecate
implicit lossy conversions, like this. It didn't pass, despite
the fact that the person who proposed it, Bjarne Stroustrup,
justifiably had a great deal of influence in the committee.)