Search code examples
c++booststatic-castboost-implicit-cast

What is the difference between static_cast and Implicit_cast?


What is implicit_cast? when should I prefer implicit_cast rather than static_cast?


Solution

  • 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.