Automatic selection between static_cast and dynamic_cast for best performance

Viewed 148

I have to use an object factory that creates new objects of several types each of which is derived from the polymorphic base class. The type of each object is known beforehand, but the factory returns the pointer on the base class. So after construction I need to downcast that pointer to the type of specific object class. In most situation static_cast does its job perfectly, but in the case of virtual inheritance dynamic_cast must be used for downcasting. At the same time I do not want to use dynamic_cast for simple types with not-virtual inheritance from base class due to its run-time overhead.

In other words, I would like to find or make a function that will convert From-type into To-type using static_cast if it is available for this conversion (e.g. To is not virtually derived from From) or dynamic_cast otherwise.

Expected use case:

template <typename To, typename From>
To fastest_cast( From && from );

struct A { virtual ~A() = default; };
struct B : A {};
struct C : virtual A {};

int main()
{
    B b;
    fastest_cast<B*>( (A*)&b ); //expected static_cast inside

    C c;
    fastest_cast<C*>( (A*)&c ); //expected dynamic_cast inside
}

Is there anything similar to fastest_cast in std-library or in boost-library? Or it is necessary to implement the conversion function by myself (please suggest how)?

1 Answers

The concept std::derived_from seems to cover the case where you want static_cast, we just have to remove the reference or pointer for it.

template <typename To, typename From>
concept castable = (std::is_pointer_v<To> && std::is_pointer_v<std::remove_cvref_t<From>>) || (std::is_reference_v<To>)

template <typename From, typename To>
concept castable_from = std::derived_from<From, std::remove_cv_t<std::remove_pointer_t<To>>> || std::derived_from<From, std::remove_cvref_t<To>>

template <typename To, castable_from<To> From>
To fastest_cast(From&& from) requires castable<To, From>
{
    return static_cast<To>(from);
}

template <typename To, typename From>
To fastest_cast(From&& from) requires castable<To, From>
{
    return dynamic_cast<To>(from);
}
Related