如何使用 shared_ptr 在类型擦除 class 中显示基础数据
How to display underlying data in a type erasure class using shared_ptr
好的,所以我有一个非常简单的 class 使用类型擦除,使用共享指针。
class Prop
{
struct PropConcept
{
virtual ~PropConcept() {}
};
template<typename T>
struct PropModel : PropConcept
{
PropModel(const T& t) : prop(t) { }
PropModel() {}
virtual ~PropModel() {}
private:
T prop;
};
std::shared_ptr<PropConcept> prop;
public:
template<typename T>
Prop(const T& obj) : prop(new PropModel<T>(obj)) { }
Prop() {};
};
这里没有问题,但是由于它的工作方式,调试器显示了从 Prop 到 std::shared_ptr(PropContent),再到 PropModel,最后是底层模板化 prop 的完整链,其中包含实际的数据。
我想做的是编写一个 natvis 规则来显示底层数据,而不是整个链。不幸的是,我得到的最深入的是取消引用指针,这只给我留下了它指向的 PropConcept 结构。
<Type Name="Prop">
<DisplayString>{*prop}</DisplayString>
<Expand>
<Item Name="prop">(*prop)</Item>
</Expand>
</Type>
当然,我的问题是,如何遍历 "tree" 以到达 PropModel 结构的 "prop" 成员? class 本身是否需要调整,或者它是否只是纯粹的 natvis 都没有关系 - 只要类型擦除仍然存在,而且我不必扩展 4 个项目来获取数据。
在此先感谢您的帮助。
就像为 Prop::PropModel
添加逻辑一样简单:
<Type Name="Prop::PropModel<*>">
<DisplayString>{prop}</DisplayString>
<Expand>
<Item Name="prop">prop</Item>
</Expand>
</Type>
我用
测试过
Prop p1{};
Prop p2{ 42 };
Prop p3{ std::string{"x"} };
显示为
如您所见,Prop
类型的代码不是最佳的。它可以检查空的 shared_ptr
并为此额外显示。如果您希望某些类型以不同方式显示,例如 int
s 显示为十进制,我的 Prop::PropModel
逻辑也可以改进。
顺便说一句,你应该启用MSVC代码分析。您的代码触发了一些警告。
我最终更接近于 Werner Henze 的答案,但上述答案提供了我需要的最终信息。为了完成起见,下面是我对此 class 的最终 natvis,以及它在调试器中的显示方式的图片。在这种情况下,shared_ptr 指向 std::vector<int>
<Type Name="Prop">
<DisplayString>{*prop}</DisplayString>
<Expand>
<ExpandedItem>(*prop)</ExpandedItem>
</Expand>
</Type>
<Type Name="Prop::PropModel<*>">
<DisplayString>{prop}</DisplayString>
<Expand>
<ExpandedItem>prop</ExpandedItem>
</Expand>
</Type>
这导致...
好的,所以我有一个非常简单的 class 使用类型擦除,使用共享指针。
class Prop
{
struct PropConcept
{
virtual ~PropConcept() {}
};
template<typename T>
struct PropModel : PropConcept
{
PropModel(const T& t) : prop(t) { }
PropModel() {}
virtual ~PropModel() {}
private:
T prop;
};
std::shared_ptr<PropConcept> prop;
public:
template<typename T>
Prop(const T& obj) : prop(new PropModel<T>(obj)) { }
Prop() {};
};
这里没有问题,但是由于它的工作方式,调试器显示了从 Prop 到 std::shared_ptr(PropContent),再到 PropModel,最后是底层模板化 prop 的完整链,其中包含实际的数据。
我想做的是编写一个 natvis 规则来显示底层数据,而不是整个链。不幸的是,我得到的最深入的是取消引用指针,这只给我留下了它指向的 PropConcept 结构。
<Type Name="Prop">
<DisplayString>{*prop}</DisplayString>
<Expand>
<Item Name="prop">(*prop)</Item>
</Expand>
</Type>
当然,我的问题是,如何遍历 "tree" 以到达 PropModel 结构的 "prop" 成员? class 本身是否需要调整,或者它是否只是纯粹的 natvis 都没有关系 - 只要类型擦除仍然存在,而且我不必扩展 4 个项目来获取数据。
在此先感谢您的帮助。
就像为 Prop::PropModel
添加逻辑一样简单:
<Type Name="Prop::PropModel<*>">
<DisplayString>{prop}</DisplayString>
<Expand>
<Item Name="prop">prop</Item>
</Expand>
</Type>
我用
测试过Prop p1{};
Prop p2{ 42 };
Prop p3{ std::string{"x"} };
显示为
如您所见,Prop
类型的代码不是最佳的。它可以检查空的 shared_ptr
并为此额外显示。如果您希望某些类型以不同方式显示,例如 int
s 显示为十进制,我的 Prop::PropModel
逻辑也可以改进。
顺便说一句,你应该启用MSVC代码分析。您的代码触发了一些警告。
我最终更接近于 Werner Henze 的答案,但上述答案提供了我需要的最终信息。为了完成起见,下面是我对此 class 的最终 natvis,以及它在调试器中的显示方式的图片。在这种情况下,shared_ptr 指向 std::vector<int>
<Type Name="Prop">
<DisplayString>{*prop}</DisplayString>
<Expand>
<ExpandedItem>(*prop)</ExpandedItem>
</Expand>
</Type>
<Type Name="Prop::PropModel<*>">
<DisplayString>{prop}</DisplayString>
<Expand>
<ExpandedItem>prop</ExpandedItem>
</Expand>
</Type>
这导致...