2011-07-08 5 views
8

Quiero calcular factorial en tiempo de compilación. Encontré alguna manera de resolver el problema, pero quiero saber si hay alguna otra solución para este problema sin usar enum s. Aquí la solución que usa enum s.¿Es posible calcular el número factorial en tiempo de compilación, pero sin enumeraciones

#include <iostream> 
template <int n> 
struct fact 
{ 
    enum{value = n*fact<n-1>::value}; 
}; 

template<> 
struct fact<1> 
{ 
    enum{value = 1}; 
}; 

int main() 
{ 
    std::cout << fact<10>::value; 
} 

Si no hay otra solución, por favor describir por qué los enum s son imprescindible.

+0

http://en.wikipedia.org/wiki/Template_metaprogramming, es [una muestra] (http: //en.wikipedia. org/wiki/Template_metaprogramming # Compile-time_class_generation) – sehe

Respuesta

10

Si bien hay notaciones alternativas, está escrito de esa manera debido a que más compiladores aceptan que la notación de estilo de enumeración. El lenguaje admite miembros de la clase const integral-type con una inicialización en línea, pero algunos compiladores no son compatibles con el estándar en ese sentido. En los compiladores que son compatibles en este sentido, las siguientes obras muy bien:

#include <iostream> 
template <unsigned int n> 
struct fact 
{ 
    static const unsigned int value = n*fact<n-1>::value; 
}; 

template<> 
struct fact<0> 
{ 
    static const unsigned int value = 1; 
}; 

int main() 
{ 
    std::cout << fact<10>::value << "\n"; 
} 
+0

hecho <0> debería ser probablemente el caso base (0! = 1) –

+0

la misma solución se puede encontrar en http://en.wikipedia.org/wiki/Template_metaprogramming – sehe

+0

La solución en el artículo de wikipedia utiliza la versión enum. El uso de enumeraciones no es obligatorio aquí. –

7

Reemplazar,

enum{value}; 

con,

static int const value; // or unsigned int 

enum s son imprescindible, ya que supone que debe ser resuelto en tiempo de compilación. Lo que asegura que cualquier resultado que haya calculado debe haberse hecho en tiempo de compilación. Otro tipo es static int const (significa cualquier tipo integral).

Para ilustrar:

enum E { 
X = strlen(s); // is an error, because X is a compile time constant 
}; 
+0

Las enumeraciones no son obligatorias aquí. El lenguaje permite a los miembros de const estáticos de tipo integral tener un valor inicial. Los enumerados son obligatorios solo para los compiladores que no cumplen (aparentemente en gran medida). –

+0

@iammilind gracias por la respuesta. Me gustaría saber por qué es necesario escribir 'static int const' porque' static int' no es aceptable. –

+0

@Samvel, porque 'static int' no se resuelve en tiempo de compilación; así incluso si lo haces. Quiere ser una constante de tiempo de compilación. – iammilind

7

Como alternativa, puede utilizar los miembros static const:

template <unsigned int n> 
struct fact { static const unsigned int value = n * fact<n-1>::value; } 
Cuestiones relacionadas