よく引き合いに出されるのが、2数を比較するプログラムです。
int型の2つの整数を比較して、大きい方を返すプログラムを考えてみましょう。
比較する2数がint型と決まっていればよいのですが、いろいろなデータ型の 2数を比較する関数が必要となれば、そのデータ型の数だけ関数が必要となります。 中身は同じなのに面倒くさいですね。そこで登場するのが関数のテンプレート機能です。 まず、関数テンプレートの書き方ですが次のようにします。int big(int a, int b) { if (a > b) return a; if (a < b) return b; if (a == b) return 0; }
MYTYPEの所は自分で好きな名前にしてかまいません。この例ではMYTYPEのところに 任意のデータ型が来ます。しかし、最初のMYTYPEがint型であれば、他のMYTYPEのところも int型になります。もちろんtemplate <typename MYTYPE> MYTYPE myfunction(MYTYPE data1, MYTYPE data2) { ... }
というように戻り値や、引数に指定したデータ型が来ても問題ありません。template <typename MYTYPE> char *yourfunction(int data1, MYTYPE data2, double data3)
では、例題を見てみましょう。
これは、データ型が等しい2数を比較して、大きい方のデータを返すプログラムです。 2数が等しいときは0を返します。どのような結果が出るか予想してみてください。 「粂井」と「田中」の比較はchar型へのポインタの比較となります。 その時のシステムの状況で結果が異なる可能性があります。// functemp.cpp #include <stdio.h> template <typename MYTYPE> MYTYPE myfunction(MYTYPE data1, MYTYPE data2) { if (data1 > data2) return data1; if (data1 < data2) return data2; if (data1 == data2) return 0; } int main() { unsigned int ans1; double ans2; char ans3; int ans4; char *ans5; ans1 = myfunction(5, 10); ans2 = myfunction(0.3, -2.1); ans3 = myfunction('a', 'c'); ans4 = myfunction(-20, 3); ans5 = myfunction("粂井", "田中"); printf("ans1 = %d, ans2 = %f, ans3 = %c, ans4 = %f\n", ans1, ans2, ans3, ans4); printf("ans5 = %s\n", ans5); return 0; }
さて、2数比較では100と100.35のように異なるデータ型を比較したいときも あるでしょう。この場合は強制的に型キャストして使う方法もあります。 テンプレート関数を呼び出すときに次のように指定します。
こうすることにより、指定の型にキャストされます。func<double>(2, 1.3);
この場合のサンプルを見てください。
どのような結果になるでしょうか。実験してみてください。// functemp2.cpp #include <stdio.h> template <typename X> char *func(X x, X y) { if (x > y) return "前者が大きい"; if (x < y) return "後者が大きい"; if (x == y) return "両者は等しい"; } int main() { printf("%s\n", func<double>(2, 1.3)); printf("%s\n", func<double>('A', 100)); printf("%s\n", func<float>('A', 0x41)); printf("%s\n", func<char *>("def", "jjj")); return 0; }
さて、少し古い本には次のような書き方をしているものもあります。
古いコンパイラでtypenameがサポートされていない場合はこのキーワードの代わりに classを使います。または、typenameをdefineしてしまってもよいでしょう。template <class X> char *func(X x, X y)
#define typename class
の一文をソースファイルの最初に書いておきます。
さて、関数テンプレートがあるのだから、クラステンプレートもあるのだろうと 予想されます。実際にあります。次回はクラステンプレートをやります。
Update Jun/20/2000 By Y.Kumei