ZhuZhi
ZhuZhi

Reputation: 48

Specific C++ Macro

I would like a C++ Macro that will turn something that looks like this:

safe_cast<Type>(object)

into

Assert(dynamic_cast<Type>(object))

Is this possible?

I could do it using: safe_cast(Type, object), but it's not what I am after.

Upvotes: 0

Views: 113

Answers (2)

Quentin
Quentin

Reputation: 63124

This cannot be a macro, but surely a function template will be fine:

template <class U, class T>
U safe_cast(T *const obj) {
    auto * const p = dynamic_cast<U>(obj);
    assert(p);
    return p;
}

Call as you would dynamic_cast with a pointer.

Upvotes: 2

Thomas Russell
Thomas Russell

Reputation: 5980

Don't use a macro. There's no reason why we cannot use a template function here, and so we should!

template <typename T, typename U>
T safe_cast_helper( U& u, std::true_type )
{
    try {
        return dynamic_cast<T>(u);
    }
    catch (std::bad_cast& e)
    {
        assert( false && "Exception thrown!" ); // Or something better!
    }
}

template <typename T, typename U>
T safe_cast_helper( U& u, std::false_type )
{
    auto ptr = dynamic_cast<T>(u);
    assert( ptr );
    return ptr;
}

template <typename T, typename U>
T safe_cast( U& u )
{
    return safe_cast_helper<T>( u, std::is_reference<T>::type() );
}

You can use this as you would normally use a dynamic_cast, with either a reference or a pointer. I would, however, recommend improving the error reporting somewhat! Perhaps a write to log or something would be prudent before assert'ing out.

Upvotes: 1

Related Questions