あぁテンプレートよ

アバター
GRAM
記事: 164
登録日時: 14年前
住所: 大阪

あぁテンプレートよ

投稿記事 by GRAM » 14年前

今現在オイラー角を扱う構造体を作ってるところです

CODE:

struct X_{};
struct Y_{ };
struct Z_{};

template 
struct EulerAngles{
	static const NType PI;
	static const NType PIPer2;

	EulerAngles(NType a_, NType b_, NType c_):a(a_),b(b_),c(c_){}
	void Wrap();
	NType a,b,c;
};
PIをなんでそんなところで宣言してるのかとか、角度がabcってどうなのよとか(こっちはもっといいやつを知りたい・・φとかΘとか半角ねーよっていうw)
突っ込みたいところはたくさんあると思うんですが、取りあえずそこはどうでもいいんです。
見ての通り毎度大好きなテンプレートです。
オイラー角は回転軸の選び方に任意性があるため、それらを区別してやります。(後に加算とかの時に制限を加えるため)
OK.このアプローチに問題があるような気もしないではないですが、今のところなにも難しくはないです。


さて問題はvoid Wrap()というメンバ関数。
こいつは角度を丸めてやり、向きの一意性を保証する関数です。たぶんオイラー角には必須でしょう。
OK.ここまではアイディアからコーディングまで時間はかかりませんでした。
問題はWrapをどうするかの一点です。

軸の選び方によってWrapの処理の仕方は異なります。
よってWrap関数を特殊化してやらなくてはなりません。

・・・ちょっと待ってくださいよと。
EulerAnglesは保持する値の精度を変えられるようにテンプレート引数NTypeを保持しています。
よって完全な特殊化は不可能。Wrap関数を部分特殊化してやらなくてはなりません。
あ~来ましたよ。できないやつ。
関数の部分特殊化ってできないんですよね。

よし。ならばクラスを特殊化すればいい
クラス内クラスWrapperを作ってこいつにoperator()を持たせ、こいつを特殊化してやろう。Wrap関数内部でWrapperを作成してoperator()を呼び出してやればいいのだ。
そうすれば何も問題はなくなるはず。みんな幸せ・・・?
・・・考えてすぐわかった。これも無理wwあんまやらないから忘れかけてたけどクラス内クラスって制約が厳しいんでした。あーあ。
まったく、面倒なことをしてくれる。

クラスの外部にWrapperを置けばすべて解決なんですけどね。何というか悔しい。というか本来ならWrapperはprivateメンバとして隠せる予定だったんですけどね。
・・・クラス内クラスをテンプレート化してさらに余計なダミー引数を持たせればいいじゃんとかも思ったけれど、そこまでするとやりすぎ感も漂うので却下。
というかその場合特殊化するのにテンプレートを二つも書かなくちゃいけない時点でめんどくさいw

やれやれ。テンプレートはここぞというときに微妙に融通が利かないからたまにイラッとする。
・・・うーんでもほかに方法があるような気もする、単純に自分の脳みそが足りないだけかな?

まぁ取りあえず解決したから文句はないですけど。


///誤字脱字はどうやったらなくなるんだろう・・・orz
最後に編集したユーザー GRAM on 2011年7月06日(水) 02:25 [ 編集 2 回目 ]

アバター
tk-xleader
記事: 158
登録日時: 14年前

RE: あぁテンプレートよ

投稿記事 by tk-xleader » 14年前

こういうことですか?

CODE:

struct X_{};
struct Y_{ };
struct Z_{};
 
template 
struct EulerAngles{
    static const NType PI;
    static const NType PIPer2;
 
    EulerAngles(NType a_, NType b_, NType c_):a(a_),b(b_),c(c_){}
    
    template
    class Wrapper{
    };
    templateclass Wrapper{
    	static void do(){/*………*/} //←内部でNTypeは使える。
    };
    templateclass Wrapper{
    	static void do(){/*………*/} //←内部でNTypeは使える。
    };
        /*  ……… */
    templateclass Wrapper{
    	static void do(){/*………*/} //←内部でNTypeは使える。
    };
    
    void Wrap(){
    	Wrapper::do();
    }
    
    NType a,b,c;
};
違ったらごめんなさい。

アバター
GRAM
記事: 164
登録日時: 14年前
住所: 大阪

Re: あぁテンプレートよ

投稿記事 by GRAM » 14年前

そんな感じですそんな感じです。
あぁ確かにクラスの定義内に直書きすればいい話ですね。おっしゃる通り。
手間的にはこれで外部に書くのと同じになりますね。
(do関数は外部のEulerAnglesを識別するためのポインタか参照を受け取る必要が出てくると思いますが、その話はおいておいて)
さすがです。ありがとうございますm(_ _)m

アバター
tk-xleader
記事: 158
登録日時: 14年前

Re: あぁテンプレートよ

投稿記事 by tk-xleader » 14年前

しかし、テンプレートの特殊化バージョンが27通りというのはつらいですね。
オイラー角がどういうものかが分かればもうちょっと効率的な実装ができそうなのですが…