編集:私はSFINAEを使用する際に簡単な間違いを犯しました。コンパイルエラーが解決されたので、私は以下のように言います。しかし、私はまだについて興味があります。の場合、この場合テンプレートパラメータを推論できません。なぜこのテンプレートパラメータは推論できませんか?
std::integer_sequence
の最大公約数(GCD)を計算するためのC++ 14テンプレートメタプログラムを作成したいと考えました。私はちょうど整数列の最初の2つの要素をはがし、そして-書き込まれるGCD_pair
メタ関数を使用してそれらのGCDを見つける
template <typename T, T A, T B, T... Ints>
struct GCD<std::integer_sequence<T, A, B, Ints...>> :
GCD<typename std::integer_sequence<T, GCD_pair<T, A, B>::value, Ints...>> {};
template <class T, T A, T B>
struct GCD<std::integer_sequence<T, A, B>> :
GCD_pair<T, A, B> {};
int main() {
using seq = std::integer_sequence<int, 65537, 5, 10>;
cout << GCD<seq>::value << endl;
return 0;
}
:いくつかの工夫の後、私はこのほとんど完全な例を思い付きました。次に、GCD
をGCD_pair
の結果と残りの要素に適用します。 GCD_pair
の
"明白な" 実装はコンパイルされません:
// This doesn't work either:
// template parameters not deducible in partial specialization
template <typename T, T M, T N, typename = void>
struct GCD_pair : std::integral_constant<T, M> {};
template <typename T, T M, T N, typename std::enable_if<(M % N != 0)>::type>
struct GCD_pair<T, M, N, void> : std::integral_constant<T, GCD_pair<T, N, M % N>::value> {};
編集:
// This does not work:
// type 'T' of template argument '0' depends on a template parameter
template <typename T, T M, T N>
struct GCD_pair : std::integral_constant<T, GCD_pair<T, N, M % N>::value> {};
template <typename T, T M>
struct GCD_pair<T, M, 0> : std::integral_constant<T, M> {};
だから私はSFINAEを使用して、別の可能な実装を試してみました私は、エラーをしました。 SFINAEの私の使用を修正する下記の答えを見てください。しかし、私はまだ質問に興味があります:
なぜテンプレートパラメータtypename std::enable_if<(M % N != 0)>::type
は推論できませんか?原則的にと推測できないか、この場合のようなパラメータが実際にはであると推測できますか?言い換えれば、これはコンパイラの実装監視と見なすことができますか?
私はbool
テンプレートパラメータで条件(M % N != 0
)を本質的に「隠す」ことによって、a slightly different versionを実装することができました。しかし、と0
とoperator!=
との比較は、すべてのC++の整数型で完全に定義されているため、上記の両方が妥当な実装であると思います。
さらに、「GCD」は、1次テンプレートを必要とする。 'テンプレート構造体GCD;'。 –
Corristo
確かに!愚かな私、私は簡単な間違いをした。 – JohnDuck
私はSFINAEの使用に間違いがあることを指摘したので、すぐにこれを受け入れました。テンプレートパラメータを推測できないのはなぜですか? – JohnDuck