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;
};
突っ込みたいところはたくさんあると思うんですが、取りあえずそこはどうでもいいんです。
見ての通り毎度大好きなテンプレートです。
オイラー角は回転軸の選び方に任意性があるため、それらを区別してやります。(後に加算とかの時に制限を加えるため)
OK.このアプローチに問題があるような気もしないではないですが、今のところなにも難しくはないです。
さて問題はvoid Wrap()というメンバ関数。
こいつは角度を丸めてやり、向きの一意性を保証する関数です。たぶんオイラー角には必須でしょう。
OK.ここまではアイディアからコーディングまで時間はかかりませんでした。
問題はWrapをどうするかの一点です。
軸の選び方によってWrapの処理の仕方は異なります。
よってWrap関数を特殊化してやらなくてはなりません。
・・・ちょっと待ってくださいよと。
EulerAnglesは保持する値の精度を変えられるようにテンプレート引数NTypeを保持しています。
よって完全な特殊化は不可能。Wrap関数を部分特殊化してやらなくてはなりません。
あ~来ましたよ。できないやつ。
関数の部分特殊化ってできないんですよね。
よし。ならばクラスを特殊化すればいい
クラス内クラスWrapperを作ってこいつにoperator()を持たせ、こいつを特殊化してやろう。Wrap関数内部でWrapperを作成してoperator()を呼び出してやればいいのだ。
そうすれば何も問題はなくなるはず。みんな幸せ・・・?
・・・考えてすぐわかった。これも無理wwあんまやらないから忘れかけてたけどクラス内クラスって制約が厳しいんでした。あーあ。
まったく、面倒なことをしてくれる。
クラスの外部にWrapperを置けばすべて解決なんですけどね。何というか悔しい。というか本来ならWrapperはprivateメンバとして隠せる予定だったんですけどね。
・・・クラス内クラスをテンプレート化してさらに余計なダミー引数を持たせればいいじゃんとかも思ったけれど、そこまでするとやりすぎ感も漂うので却下。
というかその場合特殊化するのにテンプレートを二つも書かなくちゃいけない時点でめんどくさいw
やれやれ。テンプレートはここぞというときに微妙に融通が利かないからたまにイラッとする。
・・・うーんでもほかに方法があるような気もする、単純に自分の脳みそが足りないだけかな?
まぁ取りあえず解決したから文句はないですけど。
///誤字脱字はどうやったらなくなるんだろう・・・orz