Допустим, мне нужна следующая структура:
template<class Type, int32 SIZE>
struct TSH2SizedArray
{
inline void Add(const Type & Value);inline Type & operator[](int32 Index);
inline const Type & operator[](int32 Index)const;
private:
uint8 Data[SIZE * sizeof(Type)];
int32 ElemCount = 0;
};template<class Type, int32 SIZE>
inline void TSH2SizedArray<Type, SIZE>::Add(const Type & Value)
{
assert(0 <= ElemCount && ElemCount < SIZE);
*((Type*)(Data + ElemCount++ * sizeof(Type))) = Value;
}
template<class Type, int32 SIZE>
inline Type & TSH2SizedArray<Type, SIZE>::operator[](int32 Index)
{
assert(0 <= Index && Index < ElemCount);
return *((Type*)(Data + Index * sizeof(Type)));
}
template<class Type, int32 SIZE>
inline const Type & TSH2SizedArray<Type, SIZE>::operator[](int32 Index)const
{
assert(0 <= Index && Index < ElemCount);
return *((Type*)(Data + Index * sizeof(Type)));
}
И следующее в моем файле natvis:
<Type Name="TSH2SizedArray<*,*>">
<DisplayString>TotalItemCount={ElemCount} (via natvis debug)</DisplayString>
<Expand>
<Item Name="TotalItemCount">ElemCount</Item>
<ArrayItems>
<Size>ElemCount</Size>
<ValuePointer>($T1*)Data</ValuePointer>
</ArrayItems>
</Expand>
</Type>
Сегодня я понял, что помощь отладки, предоставленная файлом natvis, не работает в этой ситуации:
void MyFunc()
{
struct CMyLocalStruct
{
int ValueA;
int ValueB;
};
TSH2SizedArray<CMyLocalStruct, 256> Array;
Array.Add(CMyLocalStruct(1,2));
}
Но работает в этом:
// File scope
struct CMyLocalStruct
{
int ValueA;
int ValueB;
};
void MyFunc()
{
TSH2SizedArray<CMyLocalStruct, 256> Array;
Array.Add(CMyLocalStruct(1,2));
}
Если у кого-то есть решение, я был бы очень благодарен, потому что это своего рода ограничение. Но для меня это похоже на ошибку.
Локальная структура — это тип, который по-разному помечается компилятором. Так что MSVC дает ему имя вроде:
`MyFunc'::`2'::CMyLocalStruct
Натвис смотрит на линию
($T1*))Data
и заменяет $T1
с параметром шаблона, который в данном случае является локальной структурой и получает:
(`MyFunc'::`2'::CMyLocalStruct*)Data
Наконец то жалуется
Error: identifier "`MyFunc'" is undefined
Что для меня выглядит как ошибка, потому что он должен продолжать читать остальную часть типа, но я не уверен.
Обходной путь, который я нашел, — объявить псевдоним для параметра шаблона в структуре с помощью using
заявление:
template<class Type, int32 SIZE>
struct TSH2SizedArray
{
inline void Add(const Type & Value);inline Type & operator[](int32 Index);
inline const Type & operator[](int32 Index)const;
using myType = Type; // natvis will interpret this correctly
private:
uint8 Data[SIZE * sizeof(Type)];
int32 ElemCount = 0;
};
А затем используйте псевдоним:
<Type Name="TSH2SizedArray<*,*>">
<DisplayString>TotalItemCount={ElemCount} (via natvis debug)</DisplayString>
<Expand>
<Item Name="TotalItemCount">ElemCount</Item>
<ArrayItems>
<Size>ElemCount</Size>
<ValuePointer>(myType*)Data</ValuePointer>
</ArrayItems>
</Expand>
</Type>
Наконец, natvis действительно показывает правильную интерпретацию для локального типа и, по иронии судьбы, он показывает имя локального типа, которое он не мог интерпретировать ранее:
Других решений пока нет …