【问题标题】:How long can template compilation really take?模板编译真正需要多长时间?
【发布时间】:2009-04-22 13:22:03
【问题描述】:

模板元编程可用于在编译时而不是在运行时计算诸如阶乘之类的东西。我听说一些编程竞赛引入了对编译时间的限制,正是为了消除模板元编程的滥用。

是否有任何使用模板需要非常非常长的时间(比如几个小时)才能编译的看似无辜的示例?

【问题讨论】:

    标签: c++ templates compilation


    【解决方案1】:

    模板机制是图灵完备的。这意味着至少在理论上,任何可以完成的计算都可以在编译时以这种方式完成(在实践中,您可能会很快遇到模板深度等方面的硬限制,但这取决于编译器)。

    您是否愿意这样做是一个单独的问题。您可以使用昂贵的算法轻松匹配“编译时间”的标准。但也有更实用的代码如this one implementing an FFT;给一个足够大的数据集,这将需要一段时间......

    【讨论】:

    • 在 N=1000 的 Core2 Duo 2,66 上大约需要 25 秒。这令人印象深刻,但不是很长。而且这段代码绝对不是看天真。
    • N=1000 对于 FFT 来说根本不是很大。我应该清楚,我的意思是它“更实用”不是因为这是你想要计算 FFT 的方式,而是因为它是一个非常有用的算法(并且在所有地方都使用)而不是实现一些只是为了需要很长时间(喜欢和阿克曼函数求值)
    【解决方案2】:

    我听说国际信息学奥林匹克竞赛(一个这样的编程竞赛)在参赛者使用类似于this 的技术创建了一个 7 维向量后首次引入了编译时间限制。他的代码不得不在一夜之间编译,这太糟糕了。我认为这发生在 90 年代后期。

    【讨论】:

      【解决方案3】:

      试试这个(我使用 Visual Studio 2005)

      template <int M, int N>
      struct Ack 
      {
          enum { value = Ack<M - 1, Ack<M, N - 1>::value >::value };
      };
      
      template <int M>
      struct Ack<M, 0> 
      {
          enum { value = Ack<M - 1, 0>::value };
      };
      
      template <>
      struct Ack<0, 0> 
      {
          enum { value = 1 };
      };
      
      template <int N>
      struct Ack<0, N> 
      {
          enum { value = N + 1 };
      };
      
      void main()
      {
          printf("Result: %d\n",  Ack<150, 150>::value);
      }
      

      这可能看起来很糟糕,我只是想写一个等效于这个可爱的 lisp 函数

      (defun ack(m, n)
      cond ((= m 0) (+ n 1))
           ((= n 0) ack(- m 1) n)
           (t (ack (- m 1) (ack m (-n 1))) )
      )
      

      我们老师说是费马函数,但我不确定……

      【讨论】:

      • 在 Core2 Duo 2,66 上的 VC7 上使用 进行了尝试 - 大约需要 20 秒,这令人印象深刻但不是很长。较大的值会导致编译时错误。
      • 如果是 ackermann 函数,用 尝试应该会让你的计算机在得到正确结果之前爆炸!如果你设法得到 则有问题。
      • 这不是阿克曼。 Ack 的情况应该计算 Ack。是的,它应该爆炸。随着这种变化,即使使用 -ftemplate-depth=1000000,截至本评论日期的 gcc 也会出现段错误
      猜你喜欢
      • 2011-03-09
      • 2016-12-16
      • 2023-02-23
      • 1970-01-01
      • 2018-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      相关资源
      最近更新 更多