Ответ 1
TL; DR; std::any
содержит указатель на статическую функцию-член шаблонного класса. Эта функция может выполнять множество операций и специфична для данного типа, поскольку фактический экземпляр функции зависит от аргументов шаблона класса.
Реализация std::any
в libstdc++ не такая сложная, вы можете посмотреть на нее:
https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/std/any
В принципе, std::any
имеет две вещи:
- Указатель на (динамически) выделенное хранилище;
- Указатель на функцию диспетчера хранилища:
void (*_M_manager)(_Op, const any*, _Arg*);
Когда вы создаете или назначаете новый std::any
с объектом типа T
, _M_manager
указывает на функцию, специфичную для типа T
(которая на самом деле является статической функцией-членом класса, специфичного для T
):
template <typename _ValueType,
typename _Tp = _Decay<_ValueType>,
typename _Mgr = _Manager<_Tp>, // <-- Class specific to T.
__any_constructible_t<_Tp, _ValueType&&> = true,
enable_if_t<!__is_in_place_type<_Tp>::value, bool> = true>
any(_ValueType&& __value)
: _M_manager(&_Mgr::_S_manage) { /* ... */ }
Поскольку эта функция специфична для данного типа, вам не требуется RTTI для выполнения операций, требуемых std::any
.
Кроме того, легко проверить, что вы производите правильный тип в std::any_cast
. Вот ядро реализации gcc std::any_cast
:
template<typename _Tp>
void* __any_caster(const any* __any) {
if constexpr (is_copy_constructible_v<decay_t<_Tp>>) {
if (__any->_M_manager == &any::_Manager<decay_t<_Tp>>::_S_manage) {
any::_Arg __arg;
__any->_M_manager(any::_Op_access, __any, &__arg);
return __arg._M_obj;
}
}
return nullptr;
}
Вы можете видеть, что это просто проверка равенства между хранимой функцией внутри объекта, который вы пытаетесь выполнить (_any->_M_manager
), и функцией менеджера типа, который вы хотите наложить (&any::_Manager<decay_t<_Tp>>::_S_manage
).
Класс _Manager<_Tp>
на самом деле является псевдонимом либо _Manager_internal<_Tp>
либо _Manager_external<_Tp>
зависимости от _Tp
. Этот класс также используется для размещения/построения объекта для std::any
класса.