【发布时间】:2009-04-22 13:22:03
【问题描述】:
模板元编程可用于在编译时而不是在运行时计算诸如阶乘之类的东西。我听说一些编程竞赛引入了对编译时间的限制,正是为了消除模板元编程的滥用。
是否有任何使用模板需要非常非常长的时间(比如几个小时)才能编译的看似无辜的示例?
【问题讨论】:
标签: c++ templates compilation
模板元编程可用于在编译时而不是在运行时计算诸如阶乘之类的东西。我听说一些编程竞赛引入了对编译时间的限制,正是为了消除模板元编程的滥用。
是否有任何使用模板需要非常非常长的时间(比如几个小时)才能编译的看似无辜的示例?
【问题讨论】:
标签: c++ templates compilation
模板机制是图灵完备的。这意味着至少在理论上,任何可以完成的计算都可以在编译时以这种方式完成(在实践中,您可能会很快遇到模板深度等方面的硬限制,但这取决于编译器)。
您是否愿意这样做是一个单独的问题。您可以使用昂贵的算法轻松匹配“编译时间”的标准。但也有更实用的代码如this one implementing an FFT;给一个足够大的数据集,这将需要一段时间......
【讨论】:
我听说国际信息学奥林匹克竞赛(一个这样的编程竞赛)在参赛者使用类似于this 的技术创建了一个 7 维向量后首次引入了编译时间限制。他的代码不得不在一夜之间编译,这太糟糕了。我认为这发生在 90 年代后期。
【讨论】:
试试这个(我使用 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))) )
)
我们老师说是费马函数,但我不确定……
【讨论】: