When I try to use float
as a template parameter, the compiler cries for this code, while int
works fine.
Is it because I cannot use float
as a template parameter?
#include<iostream>
using namespace std;
template <class T, T defaultValue>
class GenericClass
{
private:
T value;
public:
GenericClass()
{
value = defaultValue;
}
T returnVal()
{
return value;
}
};
int main()
{
GenericClass <int, 10> gcInteger;
GenericClass < float, 4.6f> gcFlaot;
cout << "\n sum of integer is "<<gcInteger.returnVal();
cout << "\n sum of float is "<<gcFlaot.returnVal();
return 0;
}
Error:
main.cpp: In function `int main()':
main.cpp:25: error: `float' is not a valid type for a template constant parameter
main.cpp:25: error: invalid type in declaration before ';' token
main.cpp:28: error: request for member `returnVal' in `gcFlaot',
which is of non-class type `int'
I am reading "Data Structures for Game Programmers" by Ron Penton, the author passes a float
, but when I try it it doesn't seem to compile.
If you don't need the double to be a compile-time constant, you can pass it in as a pointer:
The current C++ standard does not allow
float
(i.e. real number) or character string literals to be used as template non-type parameters. You can of course use thefloat
andchar *
types as normal arguments.Perhaps the author is using a compiler that doesn't follow the current standard?
THE SIMPLE ANSWER
The standard doesn't allow floating points as non-type template-arguments, which can be read about in the following section of the C++11 standard;
But.. but.. WHY!?
It is probably due to the fact that floating point calculations cannot be represented in an exact manner. If it was allowed it could/would result in erroneous/weird behavior when doing something as this;
We meant to call the same function twice but this might not be the case since the floating point representation of the two calculations isn't guaranteed to be exactly the same.
How would I represent floating point values as template arguments?
With
C++11
you could write some pretty advanced constant-expressions (constexpr) that would calculate the numerator/denominator of a floating value compile time and then pass these two as separate integer arguments.Remember to define some sort of threshold so that floating point values close to each other yields the same numerator/denominator, otherwise it's kinda pointless since it will then yield the same result previously mentioned as a reason not to allow floating point values as non-type template arguments.