What is the difference between static_cast and Implicit_cast?
Prefer implcit_cast if it is enough in your situation. implicit_cast is less powerful and safer than static_cast.
For example, downcasting from a base pointer to a derived pointer is possible with static_cast but not with implicit_cast. The other way around is possible with both casts. Then, when casting from a base to a derived class, use implicit_cast, because it keeps you safe if you confuse both classes.
Also keep in mind that implicit_cast is often not needed. Using no cast at all works most of the time when implicit_cast does, that's where 'implicit' comes from. implicit_cast is only needed in special circumstances in which the type of an expression must be exactly controlled, to avoid an overload, for example.
I'm copying over from a comment i made to answer this comment at another place.
You can down-cast with
static_cast
. Not so withimplicit_cast
.static_cast
basically allows you to do any implicit conversion, and in addition the reverse of any implicit conversion (up to some limits. you can't downcast if there is a virtual base-class involved). Butimplicit_cast
will only accept implicit conversions. no down-cast, novoid*->T*
, noU->T
if T has only explicit constructors for U.
Note that it's important to note the difference between a cast and a conversion. In the following no cast is going on
int a = 3.4;
But an implicit conversion happens from double to int. Things like an "implicit cast" don't exist, since a cast is always an explicit conversion request. The name construct for boost::implicit_cast
is a lovely combination of "cast using implicit conversions". Now the whole implementation of boost::implicit_cast
is this (explained here):
template<typename T> struct identity { typedef T type; };
template<typename Dst> Dst implicit_cast(typename identity<Dst>::type t)
{ return t; }
The idea is to use a non-deduced context for the parameter t
. That will avoid pitfalls like the following:
call_const_version(implicit_cast(this)); // oops, wrong!
What was desired is to write it out like this
call_const_version(implicit_cast<MyClass const*>(this)); // right!
The compiler can't deduce what type the template parameter Dst
should name, because it first must know what identity<Dst>
is, since it is part of the parameter used for deduction. But it in turn depends on the parameter Dst
(identity
could be explicitly specialized for some types). Now, we got a circular dependency, for which the Standard just says such a parameter is a non-deduced context, and an explicit template-argument must be provided.