In VS2010, explicit is not supported for conversion function. Is this feature very new? Thanks.
Printable View
Well, for the third time in this thread, yes, it has been introduced with C++11.
if a type is not polymorphic then there's nothing to do "dynamically", being the very idea of a dynamic down-cast relevant to polymorphic types only ( BTW, note that up-casting ( or casting to the same type ) does work with both non- and polymorphic types, no runtime check is performed in either case ). Moreover, consider that dynamic cast has a performace cost; in turn, also static_cast has a (much smaller) performance cost with respect to a reinterpret_cast; I think this fact alone can justify distinguishing between the three flavors of casts. AFAIK, note that this is in contrast with C, where pointer casts are always just a reinterpretation of their binary content, hence always a no-op; so actually, a C-coder would be surprised by the behavior of c-casts in c++: yet another reason to not use c-casts in c++ code, or relegating them to well isolated c-sections of a c++ program.
the vs2010 c++11 support is just partially implemented; yes, implementation will continue incrementally along with the next versions of visual studio, take a look hereQuote:
Originally Posted by LarryChen
I understand that. But, I'm talking about language design here. The very name they chose for it - "dynamic_cast" - prevents it from behaving any other way. Imagine for a moment that its not called that, and that it has a more general name. Now, if the class is not polymorphic, and I want to downcast it to a derived type, why should I, the dev, care about that fact? If the compiler is smart enough to figure out it's not a polymorphic type, then it might as well silently replace it with a static_cast instead, right?
So, what C++ does here is it forces its language implementation details onto the developer. I do believe the more low-level stuff you know, the better your understanding of programming is (and, I also believe it can be said for the other direction too), but from the language design standpoint, forcing implementation details on the developer is just wrong. Well, it's the established practices that do that, actually. C++ itself offers an alternative. And I like that: it allows you to make an assessment, and choose what to do in a given situation.
On Wikipedia's RTTI page it says:
Which means that a compiler warning caused by a dynamic_cast can eventually warn you that you didn't design your class properly. OK, that's a benefit, but only if you're lucky; besides, there are probably better ways to do it. A compiler warning perhaps? But, ultimately, in C++, this ends up being the responsibility of the programmer.Quote:
RTTI is available only for classes which are polymorphic, which means they have at least one virtual method. In practice, this is not a limitation because base classes must have a virtual destructor to allow objects of derived classes to perform proper cleanup if they are deleted from a base pointer.
On the other hand, I also understand that using various cast operators is a way to express your intentions in the code, and that has a certain value. The performance considerations are valid as well.
As I said before: since these language tools are already there, I don't think they should be removed from the language; the more tools there are in the toolbox, the better. I am just not convinced they should be used every single time. When the performance cost actually matters - OK. When you want to emphasize that you're doing a particular kind of casting, for some specific reason - OK. But otherwise, I don't see why a general purpose cast operator is bad.
Again, I don't mind disagreement, and appreciate all of your comments on this topic.
this is the crux of the issue: the vtable and the memory layout of polymorphic objects certainly are implementation details, but a type being polymorphic is not: C++ defines an abstract machine to hide the details of each implementation and architecture in such a way that all operations specified by the language have a well defined effect on that abstract machine, regardless of what actually is going on.
So, it's the langauge that defines what's a detail and what's not; for example, the "free store" is not a detail, the "heap" is ( although they are the same thing on most concrete machines ); similarly, "automatic storage duration" of a variable is not a detail, the "stack" is, etc ...
Now, the standard explicitly defines the "dynamic type" of an object of polymorphic type ( a concept that makes sense for polymorphic types only ); in this way, the language can well define things like dynamic_cast and type_info without invoking implementation specifics.
So, in C++ the OOP idea of inheritance is not just a relation between types; or better, a public inheritance relationship between a pair of types in c++ is a necessary but not a sufficient condition to model OOP inheritance ( for example, Liskov princinple does not hold true for such pairs, in general ); the latter requires the object to be polymorphic, or equivalently, to have a dynamic type. This is not low-level stuff, is just the way you reasonably write down OOP models in c++, at the language level.
in light of the above, it would not make much sense. With the current behavior the conversion can work, fail or fail to compile and nothing else. With such a fallback to static cast you would introduce an opportunity of UB in perfectly compiling code, why ?
Moreover, suppose we called it "try_cast<T>(v)" ( which may express the idea of a checked runtime conversion without reference to the actual types we're trying to convert ), then we would need to define the full set of rules given all pairs of types T and V working solely with our abstract machine: you would end up with essentially the same behavior of a dynamic cast, unless posing much more severe restrictions in the way objects of general type are stored in memory ( like type-reflection ), again why ?