c++shared-ptrnatvis

How to display underlying data in a type erasure class using shared_ptr


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.


Solution

  • It is as easy as adding logic for Prop::PropModel:

    <Type Name="Prop::PropModel&lt;*&gt;">
      <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

    enter image description here

    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 ints being displayed decimal.

    By the way, you should enable MSVC code analysis. Your code triggers some warnings.