While writing a library, you have sometimes to prevent users from making
mistakes. To accomplish this, you have two choices: Either include
run-time checking and throw an appropriate exception or try to catch as
much as possible during compile time. Of course, the latter should be
prefered when possible as it adds no runtime costs and forces users to
use your library properly. Read on for a small example for compile time
checks.

Situation

Let's assume we have rolled out our own RTTI system and now we want to
create a safe casting function. We only support single-inheritance to
keep things simple. It should allow downcasting from a type to a further
derived type, but not accross types. This means, if you have a class
Main and two derived types, Left and Right, it should be possible
to cast from Main to Left or Right but not from Left to Right
(at least, not directly).

What can we check?

Well, let's start what we cannot check. We have no way at compile time
to see whether a Main pointer points at runtime to a derived object or
not, so we have to do this at runtime. What we can check though is if
someone tries to assign a Left object to a Right pointer. How do we
do that? We have to check if the target is derived from the source or
the other way round - if so, one class is derived from the other.
Moreover, we have to check if both are the same - this is always safe.
Instead of implementing own is_base_of checks, we'll use the excellent
boost/type_traits library. Here's the code of our checker:

We check at compile time if the types can be casted, if so, we pass on
to a partially specialized template (AssignImplementation) which
should do the run-time check. In this example, I just used
static_cast, for the sake of simplicity. If the compile-time check
fails, AssignImplementation<false> will be called, and as it does not
exist it will result in a compile-time error like