浮動小数点型をテンプレート パラメータとして使用できない理由はありますか? その背後にある理論的根拠は何ですか?
究極の理由を示すことはできませんが、浮動ポインター値をパラメーターとして受け入れるテンプレートを特殊化すると問題が発生することは間違いなく想像できます。
浮動小数点数間の等値比較は注意が必要であり (予期しない結果が生じる場合があるという意味で)、特殊化を照合する場合、コンパイラは提供された引数とテンプレートが特殊化されている値との間で等値チェックを実行する必要があります。
もう 1 つの同様の問題は、同じクラス テンプレートの 2 つのインスタンスが実際に同じ型であるかどうかを判断することです。
template<double D>
struct X
{
// ...
};
int main()
{
X<3.0> x;
X<some_constant_expression()> y;
}
x
とy
インスタンスは同じクラスですか? これを判断するには、 と の間で等価性チェックを実行する必要が3.0
ありsome_constant_expression()
ます。
浮動小数点型へのポインタまたは参照を非テンプレート パラメータとして使用しても問題ないのに、生の浮動小数点型では問題ないのはなぜですか?
上記のシナリオに関して、ポインターに関する答えは簡単です。ポインターは整数値であり、ポインター間の比較は明確に定義されています。
参照に関しては、それらが実際にはポインターのように扱われることを示す証拠があります。
#include <type_traits>
double a = 0.0;
double b = 0.0;
template<double& D>
struct X : std::false_type { };
template<>
struct X<a> : std::true_type { }
int main()
{
static_assert(X<a>::value, "!"); // Does not fire
static_assert(X<b>::value, "!"); // Fires
}
また、C++11 標準のパラグラフ 14.4/1 ごとに:
2 つのテンプレート IDが同じクラスまたは関数を参照している場合
— [...]
— 対応する整数型または列挙型の非型テンプレート引数は、同一の値を持ち、
— [...]
— それらに対応する参照型の非型テンプレート引数は、同じ外部オブジェクトまたは関数を参照し、
— [...]
【例:
template<class E, int size> class buffer { / ... / };
buffer<char,2*512> x;
buffer<char,1024> y;
x
とが同じ型であることを宣言しy
、[...]
上記は、同じクラス テンプレートの 2 つの異なるインスタンスが実際に同じクラスであるかどうかを判断するには、テンプレート引数として使用される定数式間の等価性チェックが必要であることを示しています。