Иногда может возникнуть необходимость в создании собственной информационной системы. Это может быть полезно, если вы хотите сохранить больше информации о типах (положение, размер типа, указатели на общие функции ...) или если у вас есть представление о более компактных представлениях типов.
В приведенном ниже примере показано, как можно создать и использовать определенную пользователем информацию типа_info. Пример работает с RTTI и без него.
Рассмотрим ситуацию, когда пользователь использует только эти типы в<typeid()>:
#include <vector>
#include <string>
namespace my_namespace {
class my_class;
struct my_struct;
typedef std::vector<my_class> my_classes;
typedef std::string my_string;
} 
В этом случае пользователь может захотеть сэкономить пространство в двоичном коде и создать собственную систему типов. В этом случае<detail::typenum<>>добавляется метафункция. В зависимости от типа ввода T эта функция будет возвращать различные числовые значения.
#include <boost/type_index/type_index_facade.hpp>
namespace my_namespace { namespace detail {
    template <class T> struct typenum;
    template <> struct typenum<void>{       enum {value = 0}; };
    template <> struct typenum<my_class>{   enum {value = 1}; };
    template <> struct typenum<my_struct>{  enum {value = 2}; };
    template <> struct typenum<my_classes>{ enum {value = 3}; };
    template <> struct typenum<my_string>{  enum {value = 4}; };
    
    struct my_typeinfo {
        const char* const type_;
    };
    const my_typeinfo infos[5] = {
        {"void"}, {"my_class"}, {"my_struct"}, {"my_classes"}, {"my_string"}
    };
    template <class T>
    inline const my_typeinfo& my_typeinfo_construct() {
        return infos[typenum<T>::value];
    }
}} 
<my_type_index>— созданный пользователем класс type_index. Если вы сомневаетесь на этом этапе, вы всегда можете взглянуть на файлы<<boost/type_index/ctti_type_index.hpp>>или<<boost/type_index/stl_type_index.hpp>>. Документация для<type_index_facade>также может быть полезной.
См. осуществление<my_type_index>:
namespace my_namespace {
class my_type_index: public boost::typeindex::type_index_facade<my_type_index, detail::my_typeinfo> {
    const detail::my_typeinfo* data_;
public:
    typedef detail::my_typeinfo type_info_t;
    inline my_type_index() BOOST_NOEXCEPT
        : data_(&detail::my_typeinfo_construct<void>())
    {}
    inline my_type_index(const type_info_t& data) BOOST_NOEXCEPT
        : data_(&data)
    {}
    inline const type_info_t&  type_info() const BOOST_NOEXCEPT {
        return *data_;
    }
    inline const char*  raw_name() const BOOST_NOEXCEPT {
        return data_->type_;
    }
    inline std::string  pretty_name() const {
        return data_->type_;
    }
    template <class T>
    inline static my_type_index type_id() BOOST_NOEXCEPT {
        return detail::my_typeinfo_construct<T>();
    }
    template <class T>
    inline static my_type_index type_id_with_cvr() BOOST_NOEXCEPT {
        return detail::my_typeinfo_construct<T>();
    }
    template <class T>
    inline static my_type_index type_id_runtime(const T& variable) BOOST_NOEXCEPT;
};
} 
Обратите внимание, что в качестве основы мы использовали класс boost::typeindex::type_index_facade. Этот класс заботился обо всех вспомогательных функциях и операторах (сравнение, хеширование, омтрийинг и другие).
Наконец, мы можем использовать класс my_type_index для получения индексов типов:
my_type_index
    cl1 = my_type_index::type_id<my_class>(),
    st1 = my_type_index::type_id<my_struct>(),
    st2 = my_type_index::type_id<my_struct>(),
    vec = my_type_index::type_id<my_classes>()
;
assert(cl1 != st1);
assert(st2 == st1);
assert(vec.pretty_name() == "my_classes");
assert(cl1.pretty_name() == "my_class");
 
Обычно для того, чтобы предоставить информацию о типе среды выполнения, нам нужно зарегистрировать класс с помощью макроса. Давайте посмотрим, как макрос<MY_TYPEINDEX_REGISTER_CLASS>может быть реализован для нашего класса<my_type_index>:
namespace my_namespace { namespace detail {
    template <class T>
    inline const my_typeinfo& my_typeinfo_construct_ref(const T*) {
        return my_typeinfo_construct<T>();
    }
#define MY_TYPEINDEX_REGISTER_CLASS                                             \
    virtual const my_namespace::detail::my_typeinfo& type_id_runtime() const {  \
        return my_namespace::detail::my_typeinfo_construct_ref(this);           \
    }
}} 
Теперь, когда у нас есть MY_TYPEINDEX_REGISTER_CLASS, давайте реализуем метод<my_type_index::type_id_runtime>:
namespace my_namespace {
    template <class T>
    my_type_index my_type_index::type_id_runtime(const T& variable) BOOST_NOEXCEPT {
        
        
        return variable.type_id_runtime();
    }
}
Рассмотрим ситуацию, когда<my_class>и<my_struct>являются полиморфными классами:
namespace my_namespace {
class my_class {
public:
    MY_TYPEINDEX_REGISTER_CLASS
    virtual ~my_class() {}
};
struct my_struct: public my_class {
    MY_TYPEINDEX_REGISTER_CLASS
};
} 
Теперь следующий пример будет компилироваться и работать.
my_struct str;
my_class& reference = str;
assert(my_type_index::type_id<my_struct>() == my_type_index::type_id_runtime(reference));
 
Существует простой способ заставить<boost::typeindex::type_id>использовать свой собственный класс type_index.
Все, что нам нужно сделать, это просто определить<BOOST_TYPE_INDEX_USER_TYPEINDEX>полный путь к файлу заголовка вашего класса индекса типа:
#define BOOST_TYPE_INDEX_USER_TYPEINDEX <boost/../libs/type_index/examples/user_defined_typeinfo.hpp>
#include <boost/type_index.hpp>
Вам также нужно будет добавить несколько типдефов и макросов в файл заголовка «user_defined_typeinfo.hpp»:
#define BOOST_TYPE_INDEX_REGISTER_CLASS MY_TYPEINDEX_REGISTER_CLASS
namespace boost { namespace typeindex {
    typedef my_namespace::my_type_index type_index;
}}
Вот так! Теперь все глобальные методы и типдефы TypeIndex будут использовать ваш класс:
boost::typeindex::type_index worldwide = boost::typeindex::type_id<my_classes>();
assert(worldwide.pretty_name() == "my_classes");
assert(worldwide == my_type_index::type_id<my_classes>());