テンプレートの中でほかのテンプレートクラスのメンバ型を使う方法: typename や template の別の用法について
あるテンプレート関数(テンプレート型引数 T)で,例えば std::vector
例えば,
template <typename T1> struct TTest { struct TIn { double X; }; };
こんな構造体があったとして,
template <typename T1> void Func (void) { TTest<T1>::TIn test; test.X= 1.2; cout<<"test.X= "<<test.X<<endl; }
のような感じで TTest::TIn のインスタンスを生成したいとする.これはコンパイルエラーとなる.g++ の場合(51行目が当該箇所),
tmpl-in-struct.cpp: In function 'void Func()': tmpl-in-struct.cpp:51: error: expected ';' before 'test' tmpl-in-struct.cpp:52: error: 'test' was not declared in this scope tmpl-in-struct.cpp: In function 'void Func() [with T1 = int]': tmpl-in-struct.cpp:58: instantiated from here tmpl-in-struct.cpp:51: error: dependent-name 'TTest::TIn' is parsed as a non-type, but instantiation yields a type tmpl-in-struct.cpp:51: note: say 'typename TTest::TIn' if a type is meant
のようなエラーを吐く.よく読めば,typename を使えばいいと分かる.つまり,
typename TTest<T1>::TIn test;
とすればよい.これでコンパイルが通る.
次に,TIn もテンプレートの場合:
template <typename T1> struct TTest { template <typename T2> struct TIn { T2 X; }; };
この場合,
template <typename T1, typename T2> void Func (void) { typename TTest<T1>::TIn<T2> test; test.X= 1.2; cout<<"test.X= "<<test.X<<endl; }
とするだけだと,コンパイルエラーとなる.g++ の場合(26行目が当該箇所),
tmpl-in-struct.cpp:26: error: non-template 'TIn' used as template tmpl-in-struct.cpp:26: note: use 'TTest<T1>::template TIn' to indicate that it is a template tmpl-in-struct.cpp:26: error: declaration does not declare anything tmpl-in-struct.cpp:27: error: 'test' was not declared in this scope
のようなエラーを吐く.TTest
typename TTest<T1>::template TIn<T2> test;
とすればよいらしい.この template キーワードの使い方は今日初めて知った.