【问题标题】:Can I add a breakpoint only for a specific template instantiation?我可以仅为特定模板实例化添加断点吗?
【发布时间】:2015-02-28 01:11:28
【问题描述】:

假设我有一个模板类:

template <typename T>
class A
{
public:
   void foo() 
   {
      int i = 0; //breakpoint here only for type A<int>
   }
}

我可以在 Visual Studio 中以某种方式添加一个断点,它只会在 foo 内部中断某个实例化吗?

只喜欢A&lt;int&gt;::foo

假设我有 100 个不同类型的模板化 A 实例。

编辑:

我确实知道如何以我可以专门化某种类型的方式进行实例化。
问题是我可以在没有专业的情况下做到吗?

【问题讨论】:

    标签: c++ visual-studio debugging templates breakpoints


    【解决方案1】:

    我找到了。
    只需在您想要的行中放置一个断点(我将展示一个带有 std::shared_ptr 的示例)。
    然后转到Breakpoints 窗口,注意当它中断时,断点旁边有一个小+,它将打开所有不同的实例。
    粗体中的行是当前处于活动状态的断点。

    现在,很遗憾,断点窗口不会显示实际的模板实例化。
    但是,您可以使用调用堆栈来查看当前使用的是哪个实例化。 或者,您可以右键单击每个断点,然后选择“Go To Disassembly”。

    这可能会给你一个关于实际模板实例化的提示。 然后,您可以选择要保持活动的断点和类型。

    编辑: 您还可以将 Function 列添加到 Breakpoints 窗口并查看实际的模板函数。

    【讨论】:

    • 在断点窗口中,您可以通过显示函数列来查看实际的模板实例化。在断点窗口中,选择列下拉菜单下的函数。一旦 Function 列可见,您甚至可以按模板类型名称进行过滤:)
    【解决方案2】:

    您可以添加一些仅当Tint 时才会执行的代码,并在那里设置断点。您可以为此使用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&lt;char&gt;f&lt;short&gt; 已经被调用后才会触发断点。

    【讨论】:

      【解决方案3】:

      因为它是为了调试目的,所以写一个专门覆盖该实例的专门化,将断点放在那里:

      template <>
      class A<int>
      {
      public:
         void foo() 
         {
            int i = 0; //breakpoint here 
         }
      };
      

      编辑:嵌套模板 + 专业化

      由于重写你的类是不可行的,让我们在嵌套模板中实现要调试的函数,并对其进行专门化:

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

      【讨论】:

      • 这不是一个简单的类,我可以通过特殊化重新编写它。而且我不能继承它,因为它使用了 1000 行。但仍然是一个有效的想法
      • 啊,如果这 1000 次使用可以容纳专业化的 typedef 而不是专业化本身,那么您就得救了。
      • @didierc 你总是可以写一个丑陋的宏... :)
      猜你喜欢
      • 2016-08-12
      • 2018-06-19
      • 1970-01-01
      • 2019-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多