C
CplusplusNewbie
I'm concerned about this code for generating Fibonacci numbers which
is pasted from a website.
As I understand it, this is not really a template design at all
because only one type is used -- integers -- whereas the purpose of
templates is to allow generalizations across multiple types.
The reason the language of templates is used (it seems to me) is that
this is a trick to avoid recursive function calls, and take advantage
of compilation rules regarding templates.
Is this really the best way to avoid the recursion problem? Any other
comments on this code?
Another thing I realise is that the "uint" designation is not portable
and could be replaced by "unsigned" but that's not really what I'd
like to ask about.
Many Thanks.
#include <iostream>
#include <cassert>
using namespace std;
template<int stage>
struct Fib
{
//Make this value a constant value equal to the (stage-1) + (stage
-2)
//which the compile will generate for us and save in the types of:
// Fib<stage-1> and Fib<stage-2>. This all works because stage is
known at compile
// time, as all template parameters must be.
static const uint64_t value = Fib<stage-1>::value +
Fib<stage-2>::value;
static inline uint64_t getValue(int i)
{
if (i == stage) // Does the current class hold the given place?
{
return value; // Return it!
} else {
return Fib<stage-1>::getValue(i); // Get it from the previous
class!
}
}
};
template<> // Template specialization for the 0's case.
struct Fib<0>
{
static const uint64_t value = 1;
static inline uint64_t getValue(int i)
{
assert(i == 0);
return 1;
}
};
template<> // Template specialization for the 1's case
struct Fib<1>
{
static const uint64_t value = 1;
static inline uint64_t getValue(int i)
{
if (i == 1)
{
return value;
} else {
return Fib<0>::getValue(i);
}
}
};
int main(int, char *[])
{
//Generate (at compile time) 100 places of the Fib sequence.
//Then, (at runtime) output the 100 calculated places.
//Note: a 64 bit int overflows at place 92
for (int i = 0; i < 100; ++i)
{
cout << "n:=" << i << " => " << Fib<100>::getValue(i) << endl;
}
}
is pasted from a website.
As I understand it, this is not really a template design at all
because only one type is used -- integers -- whereas the purpose of
templates is to allow generalizations across multiple types.
The reason the language of templates is used (it seems to me) is that
this is a trick to avoid recursive function calls, and take advantage
of compilation rules regarding templates.
Is this really the best way to avoid the recursion problem? Any other
comments on this code?
Another thing I realise is that the "uint" designation is not portable
and could be replaced by "unsigned" but that's not really what I'd
like to ask about.
Many Thanks.
#include <iostream>
#include <cassert>
using namespace std;
template<int stage>
struct Fib
{
//Make this value a constant value equal to the (stage-1) + (stage
-2)
//which the compile will generate for us and save in the types of:
// Fib<stage-1> and Fib<stage-2>. This all works because stage is
known at compile
// time, as all template parameters must be.
static const uint64_t value = Fib<stage-1>::value +
Fib<stage-2>::value;
static inline uint64_t getValue(int i)
{
if (i == stage) // Does the current class hold the given place?
{
return value; // Return it!
} else {
return Fib<stage-1>::getValue(i); // Get it from the previous
class!
}
}
};
template<> // Template specialization for the 0's case.
struct Fib<0>
{
static const uint64_t value = 1;
static inline uint64_t getValue(int i)
{
assert(i == 0);
return 1;
}
};
template<> // Template specialization for the 1's case
struct Fib<1>
{
static const uint64_t value = 1;
static inline uint64_t getValue(int i)
{
if (i == 1)
{
return value;
} else {
return Fib<0>::getValue(i);
}
}
};
int main(int, char *[])
{
//Generate (at compile time) 100 places of the Fib sequence.
//Then, (at runtime) output the 100 calculated places.
//Note: a 64 bit int overflows at place 92
for (int i = 0; i < 100; ++i)
{
cout << "n:=" << i << " => " << Fib<100>::getValue(i) << endl;
}
}