Ok, so I've got a pretty straightforward class making use of type erasure, using a shared pointer.
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() {};
};
No issues here, however due to how it works, the debugger shows the complete chain from Prop, to the std::shared_ptr(PropContent), to PropModel, and finally the underlying templated prop, which contains the actual data.
What I'd like to do - is write a natvis rule to display that underlying data, instead of the entire chain. Unfortunately, the furthest I've gotten is to dereference the pointer, which just leaves me with the PropConcept struct that it points to.
<Type Name="Prop">
<DisplayString>{*prop}</DisplayString>
<Expand>
<Item Name="prop">(*prop)</Item>
</Expand>
</Type>
So of course, my question is, how do I traverse the "tree" to get to the "prop" member of the PropModel struct? It doesn't matter if the class itself needs to be tweaked, or if it's just pure natvis - just as long as the type erasure remains, and I don't have to expand 4 items to get to the data.
Thanks in advance for any help.
It is as easy as adding logic for Prop::PropModel
:
<Type Name="Prop::PropModel<*>">
<DisplayString>{prop}</DisplayString>
<Expand>
<Item Name="prop">prop</Item>
</Expand>
</Type>
I have tested with
Prop p1{};
Prop p2{ 42 };
Prop p3{ std::string{"x"} };
and the display is
As you can see your code for type Prop
is not optimal. It could check for an empty shared_ptr
and have an extra display for that. My logic for Prop::PropModel
can also be improved if you want some type to be displayed differently, for example int
s being displayed decimal.
By the way, you should enable MSVC code analysis. Your code triggers some warnings.