meta-daouble - コンパイル時浮動少数

 
id:Cryoliteさんとこに面白そうな話題みっけ。
http://d.hatena.ne.jp/Cryolite/20050621
 
さすがにBoostML追うほどの時間はないので
深く間で掘り下げることはできないですが
以前に多倍長整数をやったときにdouble型を
即値でぶっこめないかなぁと思ってました。
探してみるとdoubleの符号、指数、仮数をintで
メタっぽくやってるクラスライブラリは見つけられたんですが
あんまり気軽にはつかえない感じでした。
そこで、そのときに考えたネタのお披露目。
 
intならテンプレートで渡せるのにdoubleは無理だから
クラスに包み込んでテンプレートにしちゃおうという
誰でも思いつくような簡単な仕組みです。
データを保持する部分は、intならテンプレート非型やEnumHackなんでしょうけど
doubleの場合はインライン関数ってのがポイントです。
ほんと簡単なのですが、値ごとにクラスを作らないといけないのが面倒くさいです。
あと可読性も微妙です。マクロとか使えば多少マシになるでしょうけど。
 
んで、肝心のソース。
 

struct PI
{
    static double Value()
    {
        return 3.14;
    }
};

struct Double
{
    static double Value()
    {
        return 5.0;
    }
};

template <typename Left,typename Right>
struct Mul
{
    static double Value()
    {
        return Left::Value()*Right::Value();
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    printf("%f\n",78.5);
    //00401000  fld         qword ptr [__real@4053a00000000000 (408100h)] 
    //00401006  sub         esp,8 
    //00401009  fstp        qword ptr [esp] 
    //0040100C  push        offset string "%f\n" (4080FCh) 
    //00401011  call        printf (40101Ch) 

    printf("%f\n",
        Mul<
            Mul<Double,Double>
            ,PI
        >::Value()
    );
    //00401000  fld         qword ptr [__real@4053a00000000000 (408100h)] 
    //00401006  sub         esp,8 
    //00401009  fstp        qword ptr [esp] 
    //0040100C  push        offset string "%f\n" (408108h) 
    //00401011  call        printf (401073h) 

	return 0;
}

 
はい。そのまんまです。
やってることは半径×半径×3.14ですね。ここでは半径は5.0です。
ちなみにコメントの部分はReleaseでコンパイルした場合のアセンブラです。
ちゃんと即値の場合と同じ処理がされてます。
簡単な内容なのに他でみたことがないのは、単に僕の勉強不足か
どっかに問題があるのか・・・