Reputation: 2124
From the wikipedia I see an example of generic programming for factorial calculation done like below:
template <int N>
struct Factorial
{
enum { value = N * Factorial<N - 1>::value };
};
template <>
struct Factorial<0>
{
enum { value = 1 };
};
and from my side I wrote the code like below :
template <typename T>
T factorial(T n)
{
T x;
if (n == 1)
return 1;
x = n * factorial(n-1);
return x;
}
I read in the stackoverflow that enum is what is used in generic programming, but did not find arguments for the reasons.
So why using enum is better and what if the second code has pitfalls.
Upvotes: 5
Views: 92
Reputation: 41780
The first was required when constexpr functions didn't existed yet. Enums were the only way to store values useable at compile time when constexpr
didn't existed. Nowadays, you could implement the same template based computation using static constexpr
instead of enums. Also the first is not generic by type, it's for int
only.
The second is generic by type using a template but executed at runtime only.
Of course, templates are instantiated at compile-time but the instantiated code is runtime only by default.
With constexpr
function, you can write the same code for runtime and compile time:
template <typename T>
constexpr T factorial(T n)
{
T x{};
if (n == 1)
return 1;
x = n * factorial(n-1);
return x;
}
int main() {
int compiletime[factorial(2)];
int n;
std::cin >> n;
int runtime = factorial(n);
}
Upvotes: 8