std ::任何没有RTTI的东西,它如何工作? [英] std::any without RTTI, how does it work?

查看:88
本文介绍了std ::任何没有RTTI的东西,它如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我想使用 std :: any 我可以在RTTI关闭的情况下使用它。以下示例也可以使用带有gcc的 -fno-rtti 编译并运行。

If I want to use std::any I can use it with RTTI switched off. The following example compiles and runs as expected also with -fno-rtti with gcc.

int main()
{   
    std::any x;
    x=9.9;
    std::cout << std::any_cast<double>(x) << std::endl;
}

但是 std :: any 是否存储类型信息?如我所见,如果我使用错误类型调用 std :: any_cast ,则会得到 std :: bad_any_cast 异常

But how std::any stores the type information? As I see, if I call std::any_cast with the "wrong" type I got std::bad_any_cast exception as expected.

这是怎么实现的,或者可能只是gcc功能?

How is that realized or is this maybe only a gcc feature?

我发现 boost :: any 也不需要RTTI,但我也没有找到解决方法。 是否需要增强::是否需要RTTI?

I found that boost::any did also not need RTTI, but I found also not how that is solved. Does boost::any need RTTI?.

挖掘STL标头本身没有任何答案。

Digging into the STL header itself gives me no answer. That code is nearly unreadable to me.

推荐答案

TL; DR; std :: any 持有指向模板化类的静态成员函数的指针。该函数可以执行许多操作,并且特定于给定类型,因为该函数的实际实例取决于类的模板参数。

TL;DR; std::any holds a pointer to a static member function of a templated class. This function can perform many operations and is specific to a given type since the actual instance of the function depends on the template arguments of the class.

在libstdc ++中 std :: any 的实现不是那么复杂,您可以看一下:

The implementation of std::any in libstdc++ is not that complex, you can have a look at it:

https: //github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/std/any

std :: any 有两件事:


  • 指向(动态)a的指针分配的存储空间;

  • 指向存储管理器功能的指针:

void (*_M_manager)(_Op, const any*, _Arg*);

在构造或分配新的 std :: any T 的$ c>, _M_manager 指向特定于类型 T (实际上是特定于 T 的类的静态成员函数):

When you construct or assign a new std::any with an object of type T, _M_manager points to a function specific to the type T (which is actually a static member function of class specific to 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

Since this function is specific to a given type, you don't need RTTI to perform the operations required by std::any.

此外,在 std :: any_cast 。这是 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 )。

You can see that it is simply an equality check between the stored function inside the object you are trying to cast (_any->_M_manager) and the manager function of the type you want to cast to (&any::_Manager<decay_t<_Tp>>::_S_manage).

该类 _Manager< _Tp> 实际上是 _Manager_internal< _Tp> _Manager_external< _Tp> 取决于 _Tp
该类也用于 std :: any 类的对象的分配/构造。

The class _Manager<_Tp> is actually an alias to either _Manager_internal<_Tp> or _Manager_external<_Tp> depending on _Tp. This class is also used for allocation / construction of object for the std::any class.

这篇关于std ::任何没有RTTI的东西,它如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆