Могу ли я добавить точку останова только для определенного экземпляра шаблона?

Скажем, у меня есть шаблон:

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
        }
    }
};