配列リテラル
欲しいと思ったから書いてみたが、これはひどい。
とりあえず8要素までで。
template<int integer> struct int_ { enum { value = integer }; }; template<int integer, int decimal> struct float_ { static float const value; }; template<int integer, int decimal> float const float_<integer, decimal>::value = static_cast<float>(integer) + static_cast<float>(decimal) / 100000000.0f; template<typename Elem, std::size_t length, typename a0 = int_<0>, typename a1 = int_<0>, typename a2 = int_<0>, typename a3 = int_<0>, typename a4 = int_<0>, typename a5 = int_<0>, typename a6 = int_<0>, typename a7 = int_<0> > struct array_literal { static Elem const data[length]; }; template<typename Elem, typename a0, typename a1, typename a2, typename a3, typename a4, typename a5, typename a6, typename a7> struct array_literal<Elem, 1, a0, a1, a2, a3, a4, a5, a6, a7> { static Elem const data[1]; }; template<typename Elem, typename a0, typename a1, typename a2, typename a3, typename a4, typename a5, typename a6, typename a7> Elem const array_literal<Elem, 1, a0, a1, a2, a3, a4, a5, a6, a7>::data[] = { a0::value, }; template<typename Elem, typename a0, typename a1, typename a2, typename a3, typename a4, typename a5, typename a6, typename a7> struct array_literal<Elem, 2, a0, a1, a2, a3, a4, a5, a6, a7> { static Elem const data[2]; }; template<typename Elem, typename a0, typename a1, typename a2, typename a3, typename a4, typename a5, typename a6, typename a7> Elem const array_literal<Elem, 2, a0, a1, a2, a3, a4, a5, a6, a7>::data[] = { a0::value, a1::value, }; template<typename Elem, typename a0, typename a1, typename a2, typename a3, typename a4, typename a5, typename a6, typename a7> struct array_literal<Elem, 3, a0, a1, a2, a3, a4, a5, a6, a7> { static Elem const data[3]; }; template<typename Elem, typename a0, typename a1, typename a2, typename a3, typename a4, typename a5, typename a6, typename a7> Elem const array_literal<Elem, 3, a0, a1, a2, a3, a4, a5, a6, a7>::data[] = { a0::value, a1::value, a2::value, }; template<typename Elem, typename a0, typename a1, typename a2, typename a3, typename a4, typename a5, typename a6, typename a7> struct array_literal<Elem, 4, a0, a1, a2, a3, a4, a5, a6, a7> { static Elem const data[4]; }; template<typename Elem, typename a0, typename a1, typename a2, typename a3, typename a4, typename a5, typename a6, typename a7> Elem const array_literal<Elem, 4, a0, a1, a2, a3, a4, a5, a6, a7>::data[] = { a0::value, a1::value, a2::value, a3::value, }; template<typename Elem, typename a0, typename a1, typename a2, typename a3, typename a4, typename a5, typename a6, typename a7> struct array_literal<Elem, 5, a0, a1, a2, a3, a4, a5, a6, a7> { static Elem const data[5]; }; template<typename Elem, typename a0, typename a1, typename a2, typename a3, typename a4, typename a5, typename a6, typename a7> Elem const array_literal<Elem, 5, a0, a1, a2, a3, a4, a5, a6, a7>::data[] = { a0::value, a1::value, a2::value, a3::value, a4::value, }; template<typename Elem, typename a0, typename a1, typename a2, typename a3, typename a4, typename a5, typename a6, typename a7> struct array_literal<Elem, 6, a0, a1, a2, a3, a4, a5, a6, a7> { static Elem const data[6]; }; template<typename Elem, typename a0, typename a1, typename a2, typename a3, typename a4, typename a5, typename a6, typename a7> Elem const array_literal<Elem, 6, a0, a1, a2, a3, a4, a5, a6, a7>::data[] = { a0::value, a1::value, a2::value, a3::value, a4::value, a5::value, }; template<typename Elem, typename a0, typename a1, typename a2, typename a3, typename a4, typename a5, typename a6, typename a7> struct array_literal<Elem, 7, a0, a1, a2, a3, a4, a5, a6, a7> { static Elem const data[7]; }; template<typename Elem, typename a0, typename a1, typename a2, typename a3, typename a4, typename a5, typename a6, typename a7> Elem const array_literal<Elem, 7, a0, a1, a2, a3, a4, a5, a6, a7>::data[] = { a0::value, a1::value, a2::value, a3::value, a4::value, a5::value, a6::value, }; template<typename Elem, typename a0, typename a1, typename a2, typename a3, typename a4, typename a5, typename a6, typename a7> struct array_literal<Elem, 8, a0, a1, a2, a3, a4, a5, a6, a7> { static Elem const data[8]; }; template<typename Elem, typename a0, typename a1, typename a2, typename a3, typename a4, typename a5, typename a6, typename a7> Elem const array_literal<Elem, 8, a0, a1, a2, a3, a4, a5, a6, a7>::data[] = { a0::value, a1::value, a2::value, a3::value, a4::value, a5::value, a6::value, a7::value, };
使用例。
for (int i = 0; i < 7; ++i) { std::cout << array_literal<float, 7, float_<1,23456789>, int_<1>, float_<10,12000000> >::data[i] << std::endl; // array_literal<要素の型, 長さ, 配列に格納する値...> } /* 1.23457 1 10.12 0 0 0 0 */
なんで欲しかったかっていうと、3D扱うときに(0, 1, 0)のベクトルを書くのにわざわざfloat up[3] = {0.0f, 1.0f, 0.0f};とか書いてから関数に渡すのめんどいよなーって思ったから(逆にこれのほうがめんどい)。何でvector3(float x, float y, float z)的なコンストラクタがあるクラスが無いんだとか、その辺の詳しい理由は長ーくなるので割愛。でもそれリテラルじゃなくて静的変数やんとかまぁその辺はシャラップ。で、それとは別にfloatの値をテンプレート引数にする方法も必要だったからついでに書いた。すごい適当なやつ。もっとも、一番の理由はただ単にやってみたかったからだが。