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.
ベストアンサー1
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;
14.3.2/1 Template non-type arguments [temp.arg.nontype]
A template-argument for a non-type, non-template template-parameter shall be one of:
for a non-type template-parameter of integral or enumeration type, a converted constant expression (5.19) of the type of the template-parameter;
the name of a non-type template-parameter; or
静的記憶域期間と外部または内部リンケージを持つオブジェクト、または外部または内部リンケージを持つ関数のアドレスを指定する定数式(5.19)(関数テンプレートと関数テンプレートIDを含むが非静的クラスメンバーは除く)は、(括弧を無視して)&ID式として表現されるが、名前が関数または配列を参照する場合は&を省略でき、対応するテンプレートパラメータが参照の場合は&を省略するものとする。または
ヌルポインタ値に評価される定数式(4.10)または
ヌルメンバーポインタ値に評価される定数式(4.11)または
5.3.1 で説明されているように表現されたメンバーへのポインタ。
でも、でも、なぜ!?
これはおそらく、浮動小数点計算を正確に表現できないことが原因です。これが許可されると、次のような操作を行うときに誤った動作や奇妙な動作が発生する可能性があります。
func<1/3.f> ();
func<2/6.f> ();
同じ関数を2回呼び出すつもりだったが、2つの計算の浮動小数点表現が保証されていないため、そうではないかもしれない。その通り同じ。
浮動小数点値をテンプレート引数として表現するにはどうすればよいでしょうか?
C++11
かなり高度なものを書くことができます定数式(コンストラクター) は、コンパイル時に浮動小数点値の分子/分母を計算し、これら 2 つを別々の整数引数として渡します。
浮動小数点値が互いに近い場合、同じ結果になるように何らかのしきい値を定義することを忘れないでください。分子/分母そうでなければ、浮動小数点値を許可しない理由として前述したのと同じ結果になるので、あまり意味がありません。非型テンプレート引数。