我想为(C ++)模板类扩展一个natvis可视化器。有没有办法显示第一个模板参数的类型名称?
boost::variant<int,bool> v; v=1;
可以显示1 (int)
或类似的内容
答案 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<*>">
<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
。可能需要根据所使用的对齐方式来调整指针。