This entry assumes you are familiar with the new-style C++ cast operators, static_cast<>, dynamic_cast<>, and friends. Occasionally a situation like this arises:

Base* b = new Derived;

// ...

Derived* d = static_cast<Derived*>(b);

You know b points to a Derived object and you want to get back at that. The "type-safe" thing to do is store an additional pointer that holds the original Derived object. This may be an unreasonable request: maybe you can't afford the additional memory required, or maybe the Base* pointer is in some external library, or maybe the ownership semantics become unclear. What you really want is a way to assert in debug mode if your cast fails, but incur no overhead in release builds. Here's where checked_cast comes in!

Base* b = new Derived;
Derived* d = checked_cast<Derived*>(b);  // Checked in debug, fast in release.
And now the implementation:
template<typename T, typename U>
bool check_type(U* u) {
    return (!u || dynamic_cast<T>(u) ? true : false);
}

template<typename T, typename U>
bool check_type(U& u) {
    try {
        dynamic_cast<T>(u);
        return true;
    }
    catch (const std::bad_cast&) {
    }
    return false;
}

template<typename T, typename U>
T checked_cast(U* u) {
    assert(check_type<T, U>(u));
    return static_cast<T>(u);
}

template<typename T, typename U>
T checked_cast(U& u) {
    assert(check_type<T, U>(u));
    return static_cast<T>(u);
}

Works like a charm! Or... not. Well, it works fine in MIPSPro and Visual Studio, at least. gcc 3.x has a bug that prevents template resolution from working in this situation. The workaround is to rename the reference versions of checked_cast to checked_cast_ref.

Credit where credit due. I came up with an independent implementation of checked_cast, and when I started running into compiler troubles, I searched online for it. Turns out there are a few others. :) This post is the first place I know of that has a complete discussion.

p.s. It really sucks to format C++ as HTML? Anyone know of a tool that can automatically do this?