Могу ли я добавить точку останова только для определенного экземпляра шаблона?
Скажем, у меня есть шаблон:
template <typename T>
class A
{
public:
void foo()
{
int i = 0; //breakpoint here only for type A<int>
}
}
Могу ли я каким-то образом добавить точку останова в Visual Studio, которая будет только ломаться внутри foo
для определенного экземпляра?
Как только для A<int>::foo
?
Предположим, что у меня есть 100 шаблонных экземпляров A с разными типами.
Edit:
Я знаю, как создавать экземпляры таким образом, чтобы я мог специализироваться на определенном типе.
Вопрос в том, могу ли я сделать это без специализации?
Ответы
Ответ 1
Я нашел его.
Просто поставьте точку останова в нужной строке (я покажу пример с std:: shared_ptr < > ).
Затем перейдите в окно Breakpoints и обратите внимание, что при его разрыве рядом с точкой останова будет немного +
, которое откроет все различные экземпляры.
Строка жирная - это точка останова, которая в данный момент активна.
![Breakpoint on a templated function]()
Теперь, к сожалению, окно Breakpoints не показывает вам фактическое создание экземпляра.
Но вы можете использовать стек вызовов, чтобы узнать, какое именно средство в настоящее время используется.
Или вы можете щелкнуть правой кнопкой мыши по каждой из точек останова и выбрать " Перейти к разборке".
Это может дать вам подсказку относительно фактического экземпляра шаблона.
Затем вы можете выбрать, какие точки останова и какой тип вы хотите сохранить.
![Disassembly]()
Edit:
Вы также можете добавить столбец Функция в окно Breakpoints и посмотреть фактическую функцию шаблона.
![введите описание изображения здесь]()
Ответ 2
Вы можете добавить код, который будет выполнен, только если T
является int
, и установите там точку останова. Вы можете использовать std::is_same
для этого, или если у вас нет требуемого заголовка, и вы не хотите его добавлять, вы можете написать свою собственную тривиальную функцию:
template <typename T>
bool isint() { return false; }
template <>
bool isint<int>() { return true; }
template <typename T>
void f() {
if (isint<T>())
isint<T>();
// ^^^^^^^^^^^ set a breakpoint on that line
// rest of your function
}
int main()
{
f<char>();
f<short>();
f<int>();
f<long>();
}
Тестирование показывает, что точка останова ударяется только после того, как f<char>
и f<short>
уже были вызваны.
Ответ 3
Так как это для целей отладки, напишите специализацию, охватывающую этот экземпляр явно, поставив там точку останова:
template <>
class A<int>
{
public:
void foo()
{
int i = 0; //breakpoint here
}
};
EDIT: вложенный шаблон + специализация
Так как переписывание вашего класса не представляется возможным, пусть реализует функцию, которая будет отлаживаться внутри вложенного шаблона, и специализируемся на ней:
template<typename T>
class A
{
public:
void foo()
{
foo_impl<T,void>::exec();
}
private:
template<typename T, typename DUMMY>
struct foo_impl
{
static void exec()
{
//Default impl
}
};
template<typename DUMMY>
struct foo_impl<int,DUMMY>
{
static void exec()
{
int i = 0; //Breakpoint here
}
}
};