在我正在工作的代码库中,我们使用std::any
而不是void*
通过一些通用的非模板代码传递类。具体来说,我们使用 Visual Studio 2019、它的编译器和标准库。
为了可视化std::any
,微软已经给出了一个 natvis:
<Type Name="std::any">
<Intrinsic Name="has_value" Expression="_Storage._TypeData != 0"/>
<Intrinsic Name="_Rep" Expression="_Storage._TypeData & _Rep_mask"/>
<Intrinsic Name="type" Expression="(const type_info*)(_Storage._TypeData & ~_Rep_mask)"/>
<Intrinsic Name="_Is_trivial" Expression="has_value() && _Rep() == 0"/>
<Intrinsic Name="_Is_big" Expression="has_value() && _Rep() == 1"/>
<Intrinsic Name="_Is_small" Expression="has_value() && _Rep() == 2"/>
<DisplayString Condition="!has_value()">[empty]</DisplayString>
<DisplayString Condition="_Is_trivial() || _Is_small()">[not empty (Small)]</DisplayString>
<DisplayString Condition="_Is_big()">[not empty (Large)]</DisplayString>
<Expand>
<Synthetic Name="has_value">
<DisplayString>{has_value()}</DisplayString>
</Synthetic>
<Synthetic Name="type" Condition="has_value()">
<DisplayString>{type()}</DisplayString>
</Synthetic>
<Synthetic Name="[representation]" Condition="_Is_trivial()">
<DisplayString>(Small/Trivial Object)</DisplayString>
</Synthetic>
<Synthetic Name="[representation]" Condition="_Is_small()">
<DisplayString>(Small Object)</DisplayString>
</Synthetic>
<Synthetic Name="[representation]" Condition="_Is_big()">
<DisplayString>(Dynamic Allocation)</DisplayString>
</Synthetic>
</Expand>
</Type>
然而,这最终显示给我们(Small Object)
而不是std::string
我们存储在其中的内容。我已经设法用一些额外的行来扩展它以获取指向数据的指针:
<Item Name="[castable_ptr]" Condition="_Is_trivial()">(void*)(&_Storage._TrivialData)</Item>
<Item Name="[castable_ptr]" Condition="_Is_small()">(void*)(&_Storage._SmallStorage._Data)</Item>
<Item Name="[castable_ptr]" Condition="_Is_big()">(void*)(_Storage._BigStorage._Ptr)</Item>
但是,这会将数据显示为void*
,您必须手动将其转换为实际类型的指针std::string*
。但是,此std::any
实现/可视化还附带一个std::type_info
. (参见字段:类型)知道我们拥有哪种底层类型。
有没有办法使用它std::type_info
,以便(void*)
可以将其替换为实际存储类型的强制转换?
编辑: Visual Studio 为该类型提供的信息示例:{mydll.dll!class std::tuple<__int64,double,double,double> 'RTTI Type Descriptor'} {...}
当将地址显式转换为 std::type_info* 时,我可以_Data
在包含_DecoratedName
( .?AV?$tuple@_JNNN@std@@
) 和_UndecoratedName
( nullptr
) 的调试器中访问。不幸的是,我似乎不知道如何编写一个利用这些信息的演员表。