如何在natvis中显示模板参数类型名称?

时间:2019-01-31 10:48:12

标签: visual-c++ natvis

我想为(C ++)模板类扩展一个natvis可视化器。有没有办法显示第一个模板参数的类型名称?

boost::variant<int,bool> v; v=1;可以显示1 (int)或类似的内容

2 个答案:

答案 0 :(得分:1)

如果要将$T1显示为字符串,请用"括起来。例如,对于

<DisplayString>{*($T1*)storage_.data_.buf} {"$T1"}</DisplayString>

在您的情况下,您会看到1 "int"

答案 1 :(得分:0)

在我认为最好的解决方法是使用标准的C ++ 17 std::variant。 MSVC带有此类型的natvis,因此您可以很漂亮地查看所存储的值。

这是我刚刚编写并测试的一些natvis代码:

  <Type Name="boost::variant&lt;*&gt;">
    <DisplayString Condition="which_==0">{*($T1*)storage_.data_.buf}</DisplayString>
    <DisplayString Condition="which_==1" Optional="true">{*($T2*)storage_.data_.buf}</DisplayString>
    <DisplayString Condition="which_==2" Optional="true">{*($T3*)storage_.data_.buf}</DisplayString>
    <DisplayString Condition="which_==3" Optional="true">{*($T4*)storage_.data_.buf}</DisplayString>
    <DisplayString Condition="which_==4" Optional="true">{*($T5*)storage_.data_.buf}</DisplayString>
    <DisplayString Condition="which_==5" Optional="true">{*($T6*)storage_.data_.buf}</DisplayString>
    <DisplayString Condition="which_==6" Optional="true">{*($T7*)storage_.data_.buf}</DisplayString>
    <Expand>
      <Item Name="which">which_</Item>
      <Item Name="value0" Condition="which_==0">*($T1*)storage_.data_.buf</Item>
      <Item Name="value1" Condition="which_==1" Optional="true">*($T2*)storage_.data_.buf</Item>
      <Item Name="value2" Condition="which_==2" Optional="true">*($T3*)storage_.data_.buf</Item>
      <Item Name="value3" Condition="which_==3" Optional="true">*($T4*)storage_.data_.buf</Item>
      <Item Name="value4" Condition="which_==4" Optional="true">*($T5*)storage_.data_.buf</Item>
      <Item Name="value5" Condition="which_==5" Optional="true">*($T6*)storage_.data_.buf</Item>
      <Item Name="value6" Condition="which_==6" Optional="true">*($T7*)storage_.data_.buf</Item>
    </Expand>
  </Type>

它适用于任何boost::variant<type_or_types>

它有一个DisplayString,该变量采用变体的成员storage_并提取缓冲区buf。然后将缓冲区的地址强制转换为指向std::variant提供的类型的指针。如您在我的代码中所见,which_是基于零的,而模板参数是基于1的。我对地址不感兴趣,但对值不感兴趣,因此我在值前添加了一个*

我还添加了Expand部分,以便您可以扩展变体。这让我展示which_,并再次显示值 - 这一次列Type会显示正确的类型,你可以在我的屏幕截图看到(对变种本身的类型显示为{ {1}},但我不知道如何将类型名称添加到boost::variant<…>)。

请注意,DisplayString是必需的,因为否则,如果传递的类型参数少于7个(如Optional="true",并且natvis没有{{1} }。

如果需要更多模板参数,则可以轻松扩展代码。

如果你想要的boost::variant<int,bool>也示出了索引(作为显式值或者编码到名称$T7),则可以很容易地改变它相应地如在

DisplayString

最后但并非最不重要的一点是,请注意,我没有进行太多测试,也没有详细研究value…。我看到<DisplayString Condition="which_==0">{{which={which_} value0={*($T1*)storage_.data_.buf}}}</DisplayString> 的成员建议进行一些调整。因此,它可能是不够的,只是使用boost::variant。可能需要根据所使用的对齐方式来调整指针。

View in Debugger