参照配列の特殊化と型推論
C++テンプレートテクニックを読んでいて見慣れない構文が出てきた
template<class T,std::size_t N> struct range_iterator< T[N] > { typedef T* type; };
このT[N]で特殊化してる部分が良く分からなかったので自分なりに色々調査してみた。
まずはどういうときに呼ばれるのか試してみる。
#include <iostream> using std::cout; using std::endl; template<class T> struct value_test { static const int type = 1; }; template<class T,std::size_t N> struct value_test< T[N] > { static const int type = 2; }; template<class T> struct value_test< T* > { static const int type = 3; }; int main () { cout << value_test<int>::type << endl; cout << value_test<int[10]>::type << endl; cout << value_test<int*>::type << endl; }
これを実行すると
$ main 1 2 3
となった。つまりint[10]のようなものを渡せばT[N]となるようだ。ちなみにT[N]をT&にしてもちゃんと動く。両者の違いとしては恐らくTが配列の参照の場合のみの特殊化としてインスタンス化できるところにあるのかな。
さて、ここまではわかったのものの、「value_test
恐らく殆どの場合、型推論によって「value_test
#include <iostream> using std::cout; using std::endl; template<class T> struct value_test { static const int type = 1; }; template<class T,std::size_t N> struct value_test< T[N] > { static const int type = 2; }; template<class T> struct value_test< T* > { static const int type = 3; }; template<class T> int func (T&) { return typename value_test<T>::type; } int main () { int a; int b[10]; int* c; cout << func(a) << endl; cout << func(b) << endl; cout << func(c) << endl; }
$ main 1 2 3
上記のようなfuncというテンプレート関数を用意する。戻り値は「value_test
凄く面白い。けど、頭がスクランブルエッグだ。