1. <i id='W1R63'><tr id='W1R63'><dt id='W1R63'><q id='W1R63'><span id='W1R63'><b id='W1R63'><form id='W1R63'><ins id='W1R63'></ins><ul id='W1R63'></ul><sub id='W1R63'></sub></form><legend id='W1R63'></legend><bdo id='W1R63'><pre id='W1R63'><center id='W1R63'></center></pre></bdo></b><th id='W1R63'></th></span></q></dt></tr></i><div id='W1R63'><tfoot id='W1R63'></tfoot><dl id='W1R63'><fieldset id='W1R63'></fieldset></dl></div>

      1. <legend id='W1R63'><style id='W1R63'><dir id='W1R63'><q id='W1R63'></q></dir></style></legend>
          <bdo id='W1R63'></bdo><ul id='W1R63'></ul>

        <tfoot id='W1R63'></tfoot>

        <small id='W1R63'></small><noframes id='W1R63'>

      2. std::any 没有 RTTI,它是如何工作的?

        时间:2024-08-14
      3. <small id='S99pY'></small><noframes id='S99pY'>

        <tfoot id='S99pY'></tfoot>

            <i id='S99pY'><tr id='S99pY'><dt id='S99pY'><q id='S99pY'><span id='S99pY'><b id='S99pY'><form id='S99pY'><ins id='S99pY'></ins><ul id='S99pY'></ul><sub id='S99pY'></sub></form><legend id='S99pY'></legend><bdo id='S99pY'><pre id='S99pY'><center id='S99pY'></center></pre></bdo></b><th id='S99pY'></th></span></q></dt></tr></i><div id='S99pY'><tfoot id='S99pY'></tfoot><dl id='S99pY'><fieldset id='S99pY'></fieldset></dl></div>
            • <bdo id='S99pY'></bdo><ul id='S99pY'></ul>

                • <legend id='S99pY'><style id='S99pY'><dir id='S99pY'><q id='S99pY'></q></dir></style></legend>
                    <tbody id='S99pY'></tbody>

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

                  问题描述

                  如果我想使用 std::any 我可以在关闭 RTTI 的情况下使用它.以下示例也使用 -fno-rtti 和 gcc 按预期编译和运行.

                  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,但我也没有发现它是如何解决的.boost::any 需要 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 包含两件事:

                  Basically, std::any holds two things:

                  • 指向(动态)分配的存储的指针;
                  • 指向存储管理器函数"的指针:
                  void (*_M_manager)(_Op, const any*, _Arg*);
                  

                  当你用 T 类型的对象构造或分配一个新的 std::any 时,_M_manager 指向一个特定于type 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的gcc实现的核心:

                  Furthermore, it is easy to check that you are casting to the right type within std::any_cast. Here is the core of the gcc implementation of 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>::_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::any 没有 RTTI,它是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:Google C++ 风格指南的无例外规则;STL? 下一篇:我可以/应该从 STL 迭代器继承吗?

                  相关文章

                  <small id='C9VQ9'></small><noframes id='C9VQ9'>

                  <legend id='C9VQ9'><style id='C9VQ9'><dir id='C9VQ9'><q id='C9VQ9'></q></dir></style></legend>

                    <tfoot id='C9VQ9'></tfoot>
                    1. <i id='C9VQ9'><tr id='C9VQ9'><dt id='C9VQ9'><q id='C9VQ9'><span id='C9VQ9'><b id='C9VQ9'><form id='C9VQ9'><ins id='C9VQ9'></ins><ul id='C9VQ9'></ul><sub id='C9VQ9'></sub></form><legend id='C9VQ9'></legend><bdo id='C9VQ9'><pre id='C9VQ9'><center id='C9VQ9'></center></pre></bdo></b><th id='C9VQ9'></th></span></q></dt></tr></i><div id='C9VQ9'><tfoot id='C9VQ9'></tfoot><dl id='C9VQ9'><fieldset id='C9VQ9'></fieldset></dl></div>
                        <bdo id='C9VQ9'></bdo><ul id='C9VQ9'></ul>