> -- Сергей Губанов писал(а):
> Компилятор передаст тег типа MyMessageObject внутрь процедуры Handle неявно.

Дабы не быть голословным, вот чуть-чуть измененная реализация, в которой нет никаких "лишних байтов". В исходном примере поменялась только сигнатура хэндлера:
## Код:
```
void check_type(const oberon::tagged<X> &x)
```


oberon_cast.h:
## Код:
```
namespace oberon {

typedef const int *type_signature;

struct type_hierarchy
{
    type_signature *m_phierarchy;
    int m_cn;
};

struct type
{
    static const int k_cn_inherited = -1;
};

template <typename T>
void
init_type_info(type_signature *hierarchy)
{
    hierarchy[T::k_cn_inherited] = &T::k_cn_inherited;
    init_type_info<typename T::base>(hierarchy);
}

template <>
inline
void
init_type_info<type>(type_signature *hierarchy)
{
}

template <typename T, typename B = type>
struct inherit : B
{
    typedef B base;
    static const int k_cn_inherited = base::k_cn_inherited + 1;

    struct type_info : type_hierarchy
    {
        type_signature m_hierarchy[k_cn_inherited + 1];

        type_info()
        {
            m_phierarchy = m_hierarchy;
            m_cn = k_cn_inherited;
            init_type_info<T>(m_hierarchy);
        }
    };
};

template <typename T>
struct tagged
{
    template <typename U>
    tagged(const U &o) 
    : m_o(o)
    {
    static U::type_info s_type_info;
        this->m_type = &s_type_info;
    }

    const T &operator * () const {return m_o;}

    const T &m_o;
    const type_hierarchy *m_type;
};


template <typename T, typename U>
const T *
cast(const tagged<U> &o)
{
const type_hierarchy &dynamic_type = *o.m_type;
    if (dynamic_type.m_cn < T::k_cn_inherited
     || dynamic_type.m_phierarchy[T::k_cn_inherited] != &T::k_cn_inherited)
        return 0;

    return static_cast<const T *>(&o.m_o);    
}

} // namespace oberon
```
