- 締切済み
メタ関数の再帰停止の方法についての質問です.
メタ関数の再帰停止の方法についての質問です. 最大公倍数を求めるメタ関数を作ろうとして引数をintに固定したものはすぐ作れたのですが 引数を任意の整数にしたものを作ろうとしたところ,いろいろな方法を試みましたがどれもだめで結局以下のようにしました. template<typename IntegerT, IntegerT Rhs, IntegerT Lhs> struct gcd; template<int Rhs, int Lhs> struct gcd<int, Rhs, Lhs> { typedef int integer_type; typedef gcd<integer_type, Rhs, Lhs> type; typedef integer_type value_type; static const value_type value = gcd<integer_type, Lhs, Rhs % Lhs>::type::value; }; template<int Rhs> struct gcd<int, Rhs, 0> { typedef int integer_type; typedef gcd<integer_type, Rhs, 0> type; typedef integer_type value_type; static const value_type value = Rhs > 0 ? Rhs : -Rhs; }; template<long long Rhs, long long Lhs> struct gcd<long long, Rhs, Lhs> { typedef long long integer_type; typedef gcd<integer_type, Rhs, Lhs> type; typedef integer_type value_type; static const value_type value = gcd<integer_type, Lhs, Rhs % Lhs>::type::value; }; template<long long Rhs> struct gcd<long long, Rhs, 0ll> { typedef long long integer_type; typedef gcd<integer_type, Rhs, 0ll> type; typedef integer_type value_type; static const value_type value = Rhs > 0ll ? Rhs : -Rhs; }; しかし,この方法だと考えられる整数全てに対して特殊化を定義せねばならず何のためにテンプレートを使っているのかわかりません. テンプレートのインスタンス化の順序を考えてみるとコンパイル時に再帰を停止するための条件が普通に考えたものとは異なるように思うのですが,どのようにすればもっと簡単に一般の整数型(short,long等)に対してメタ関数を定義できるでしょうか?
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- Tacosan
- ベストアンサー率23% (3656/15482)
- 麻野 なぎ(@AsanoNagi)
- ベストアンサー率45% (763/1670)
- 麻野 なぎ(@AsanoNagi)
- ベストアンサー率45% (763/1670)
- 麻野 なぎ(@AsanoNagi)
- ベストアンサー率45% (763/1670)
- Tacosan
- ベストアンサー率23% (3656/15482)
お礼
私はコンパイラの挙動等わからないことがいっぱいあるのでうまく説明できないところがあり,ご迷惑をおかけしたかも知れません.ただインスタンス化の順序で追っかけて考えたときの挙動とは異なる挙動をしているように思い,そこが良くわからないのでメタ関数を作ろうとすると試行錯誤的な作り方になってしまい先を見通すことがうまくできないでいます. 有理数の通分と似たことになりますが,実数の整数化に最大公倍数を利用しようと思っていたのでご紹介のBoostの関数が使えそうです(自分で作ったものよりそちらをつかったほうが良いでしょう)いろいろとお教えいただきどうもありがとうございます. メタ関数を作るときの考え方については引き続き教えていただけるとありがたいです.