こんにちは,寺田@東工大 です.
こちらの ML には初めて投稿します.よろしくお願いします.
XP はまだよく分かっていませんが,単純に「ほかの方法論より楽しそう」というだけの
理由でこの ML を読んでます.実際に効果的なのかどうかは,実務経験がないのでいまい
ちイメージが湧かない,というのが本音です.
で,初めての投稿が全然 XP と関係なくて大変恐縮なのですが,パズルを解く感覚で階乗
計算のプログラムを解読してみましたので...
# あぁ,なんてヒマな学生なんだ(笑)
> でも,このマクロを駆使したギミック言語の延長に,generative
> programming がある,と捉えることもできますね.gp は,例えば
> こんな感じです.コンパイルタイムに階乗計算を行うための C++
> template です.(James Coplien から教わったものですが,もはや
> 解読不能)
> template <bool condition, class Then, class Else>
> struct IF { typedef Then RET; };
>
> template <class Then, class Else>
> struct IF<false, Then, Else> { typedef Else RET; };
この部分は,次のような意味ですね.
struct IF<true, Then, Else> { typedef Then RET; };
struct IF<false, Then, Else> { typedef Else RET; };
要するに,
IF<条件式, A, B>::RET
と書くと,
条件式が真の場合 → A になる
条件式が偽の場合 → B になる
すると,
> template <int n> struct fact {
> typedef
> IF<n==0, One, fact<n-1> >::RET PreviousFactorial;
> enum { RET = (n ==0)
> ? PreviousFactorial::RET
> : PreviousFactorial::RET * n};
> };
この部分は,以下のように解釈できます.
// n == 0 の場合
struct fact<0> {
enum { RET = One::RET };
};
// n > 0 の場合
struct fact<n> { // n > 0
enum { RET = fact<n-1>::RET * n };
};
ですので,
fact<n>::RET
で n! の値を得ることができます.
でも,こんなの,もっと簡単にできますよねぇ.
複雑な書き方をしたのには何か深遠な理由があったのでしょうか.
たとえばこう書いちゃえばすごく簡単です.
#incldue <iostream>
using namespace std;
template<int n>
struct fact { enum{ RET = n * fact<n-1>::RET}; };
template<>
struct fact<0> { enum{ RET = 1}; };
int main(){
cout << "5! = " << fact<5>::RET << endl;
return 0;
}
おお! もしかしてこれは,gp のりファクタリング?
と,無理やり XP ネタにもっていったところで,失礼します.
本当に XP と関係ないメールですいません.
それでは.
PS:
主に強調したかったのは IF<condition, Then, Else> なんでしょうか.
階乗を求める fact<n> は IF<condition, Then, Else> の単なる適用例であって,
メインではなかったのでは...?
確かに,IF<condition, Then, Else> は他にも使えそうです.
そう考えれば,複雑な書き方になっているのにも納得できます.