Listing 4: auto_unbox<>.

struct object_convertible 
{ 
    object_convertible ( System::Object * ); 
};
template<typename T>
class is_managed
{
    static char             select( object_convertible );
    static double __cdecl   select( ... );
    static T get();
public:
    enum { value = sizeof(select(get())) == sizeof(char) };
};
template<bool> struct auto_unbox_helper;
template<>
struct auto_unbox_helper<true> // managed
{
    template<typename T>
    struct inner
    {
        typedef T result_type;
        static T unbox( System::Object *o )
        {
            return __try_cast<T>( o );
        }
    };
};
template<>
struct auto_unbox_helper<false> // not managed
{
    template<typename T>
    struct inner
    {
        typedef T __gc& result_type;
        static T __gc& unbox( System::Object *o )
        {
            return *__try_cast<T __box*>( o );
        }
    };
};
template<typename T>
struct auto_unbox
{
    typedef typename auto_unbox_helper<is_managed<T>::value>::
        template inner<T> helper;
    static typename helper::result_type unbox( System::Object *o )
    {
        return helper::unbox( o );
    }
};