2009-04-22 11 views
6

La metaprogramación de plantillas se puede usar para calcular cosas como factorial en tiempo de compilación en lugar de durante el tiempo de ejecución. He oído que algunos concursos de programación han introducido limitaciones en el tiempo de compilación exactamente para eliminar el abuso de la metaprogramación de plantillas.¿Cuánto tiempo puede durar la compilación de plantillas?

¿Hay algún ejemplo inocente de usar plantillas que demore bastante tiempo (como varias horas) en compilarse?

Respuesta

3

He oído que la Olimpiada Internacional en Informática (un concurso de programación de este tipo) introdujo por primera vez los límites de tiempo de compilación después de que un concursante creó un vector de 7 dimensiones usando una técnica muy similar a this. Su código tuvo que ser compilado durante la noche, fue tan malo. Creo que esto ocurrió en algún momento a finales de los 90.

5

El mecanismo de plantilla es Turing-completo. Esto significa que, al menos en teoría, cualquier cálculo que se pueda hacer se puede hacer en tiempo de compilación de esta manera (en la práctica puede encontrarse con límites duros en profundidad de plantilla, etc. bastante rápido, pero esto depende del compilador).

Si desea hacer esto o no, es una pregunta separada. Puede combinar trivialmente su criterio de "horas para compilar" utilizando un algoritmo costoso. Pero también hay códigos más prácticos como this one implementing an FFT; dan que establecen una gran cantidad de datos suficientes y tardará un tiempo ...

+0

se tarda unos 25 segundos en Core2 Duo 2,66 con N = 1000. Eso es impresionante, pero no muy largo. Y este código definitivamente no está buscando inocentemente. – sharptooth

+0

N = 1000 no es muy grande en absoluto para una FFT. Debería ser claro, quise decir que era "más práctico" no porque esta es la forma en que querría calcular una FFT, sino porque es un algoritmo extremadamente útil (y utilizado en todas partes) en lugar de implementar algo solo para tomar mucho tiempo (como evaluación de la función Ackerman) – simon

3

Prueba esto (i utiliza 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); 
} 

Es tal vez parece horribble, he intentado escribir un equivalente a este función Lisp linda

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

Nuestro profesor dijo que es función de Ferma, pero no estoy seguro ...

+2

http://en.wikipedia.org/wiki/Ackermann_function –

+2

Intenté esto con <116, 116> en VC7 en Core2 Duo 2,66 - tarda unos 20 segundos, lo que es impresionante pero no muy largo . Los valores más grandes causan un error en tiempo de compilación. – sharptooth

+0

Si es una función de Ackermann, ¡probándola con <5,5> debería hacer explotar su computadora antes de obtener el resultado correcto! Si logras obtener <116,116>, entonces algo está mal. – CygnusX1

Cuestiones relacionadas