第8回は可変長テンプレートになります。 今まで可変長引数の関数を作る場合 1: #include <iostream> 2: #include <stdarg.h> 3: using namespace std; 4: 5: void func(int cnt, ...) 6: { 7: va_list ap; 8: va_start(ap, cnt); 9: 10: for (int i = 0; i < cnt; i++) 11: { 12: cout << va_arg(ap, int) << endl; 13: } 14: 15: va_end(ap); 16: } 17: 18: int main() 19: { 20: func(3, 1, 2, 3); 21: 22: return 0; 23: } このようにva_start、va_arg、va_endを使用していました。(正直可変長引数を普段書かないのでよく分かりません。) 1: #include <iostream> 2: #include <string> 3: 4: using namespace std; 5: 6: template<typename ...T> 7: void func(T... args) 8: { 9: cout << sizeof...(T) << endl;//何個引数あるかはsizeof...で確認 10: } 11: 12: //終端用ダミー 13: void argPrint() 14: { 15: } 16: 17: //unpackすれば可変長以外の引数に渡すことも 18: template<typename T, typename... Arg> 19: void argPrint(T n, Arg... args) 20: { 21: cout << n << endl; 22: argPrint(args...); 23: } 24: 25: int main() 26: { 27: //複数の型を自由に設定出来る 28: func<>();//0 29: func<int>(1);//1 30: func<int, double >(1, 1.0);//2 31: func<int, double, string>(1, 1.0, "Hello");//3 32: 33: //再帰を利用して順番に表示 34: argPrint(1, 1.5, 'c', "Hello"); 35: 36: return 0; 37: } まず、可変長テンプレートを使うには template<typename... T> void func(T... arg) { //処理 } 従来のtemplateの記述に"..."を追加すればOKです。あとはmain文の部分のように型を指定して書けば使用できます。 さて、可変長テンプレートは0以上の長さのテンプレート(9行目のsizeof...()で確認可能)なのですが、va_argのような機能はないのでそのままでは1つずつ取得することが出来ません。 argPrint(args...); のように可変長テンプレートの変数名+"..."と記述することにより、可変長テンプレート以外の引数に渡すことが出来るようになります。(オーバーロードに対しても可) 可変長テンプレートは出来ることが多く、私自身がそこまで深く使えないので、今回は簡単な書き方と使用方法のみを説明しました。 以上で可変長テンプレートの説明を終わります。 |