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 with implicit_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). But implicit_cast
will only accept implicit conversions. no down-cast, no void*->T*
, no U->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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…