Частичная специализация шаблонов C ++ и Natvis - PullRequest
1 голос
/ 20 октября 2019

Я пытаюсь создать визуализаторы отладки Visual Studio для частично специализированного типа. Например, скажем, у меня есть что-то вроде этого:

template <typename T>
struct Foo
{
    T bar;
};

template <typename T>
struct Foo<T*>
{
    T baz;
};

Без частичной специализации это было бы легко:

<Type Name="Foo&lt;*&gt;"> ... </Type>

С полной специализацией это также было бы легко:

<Type Name="Foo&lt;int&gt;"> ... </Type>

Но как мне покрыть частичную специализацию? Это даже поддерживается? Если нет, есть ли обходной путь?

1 Ответ

1 голос
/ 07 ноября 2019

Краткий ответ - Нет. Вы не можете указывать квалификаторы типов, ссылки и т. Д. В имени типа natvis <Type Name="Foo&lt;*&gt;">.

Но:

Вы можете использовать параметр typename шаблонав виде строки и сравнить с типом. Например, в атрибуте Condition узла:

<Type Name="Foo&lt;*&gt;">
  <DisplayString Condition="strcmp(&quot;$T1&quot;,&quot;short&quot;)==0">specialization short</DisplayString>
  <DisplayString Condition="strcmp(&quot;$T1&quot;,&quot;int &amp;&quot;)==0">specialization int &amp;</DisplayString>
  <DisplayString>unspecified specialization</DisplayString>
</Type>

Для Foo<short> вы увидите specialization short и unspecified specialization для других.

Пример:

template <typename T, typename U>
struct Foo
{
    T bar;
};

template <typename U>
struct Foo<int &, U>
{
    U baz;
};
int main()
{
    int gg = 0;
    Foo<short, int> a;
    Foo<int, int> b;
    Foo<int &, int> c;

Natvis:

<Type Name="Foo&lt;*,*&gt;" >
  <DisplayString Condition="strcmp(&quot;$T1&quot;,&quot;short&quot;)==0">specialization short</DisplayString>
  <DisplayString>unspecified specialization</DisplayString>
</Type>

<Type Name="Foo&lt;int&amp;,*&gt;">
  <DisplayString>partial specialization int&amp;</DisplayString>
</Type>

Результат:

strcmp

Или вы, если у вас есть какой-то уникальный член в вашем частичноспециализированный тип, можно использовать опцию Priority.

Пример:

template <typename T>
struct Foo
{
    T bar;
};

template <typename U>
struct Foo<U &>
{
    U baz;
};
int main()
{
    int g = 0;
    Foo<short> a;
    Foo<int> b;
    Foo<int &> c{g};

Натвис:

<Type Name="Foo&lt;*&gt;">
  <DisplayString>partial specialization {baz}</DisplayString>
</Type>

<Type Name="Foo&lt;*&gt;" Priority="Low">
  <DisplayString>other specialization</DisplayString>
</Type>

Результат:

Priority

...