第35章 関数のテンプレート


今回はC++のテンプレート機能についてやります。 比較的新しい機能なので古いコンパイラではサポートされていない可能性が あります。筆者の持っているVC++1.51ではサポートされていませんでした。 ここのサンプルはVC++6.0のコンソールアプリです。



よく引き合いに出されるのが、2数を比較するプログラムです。 int型の2つの整数を比較して、大きい方を返すプログラムを考えてみましょう。

int big(int a, int b) { if (a > b) return a; if (a < b) return b; if (a == b) return 0; }

比較する2数がint型と決まっていればよいのですが、いろいろなデータ型の 2数を比較する関数が必要となれば、そのデータ型の数だけ関数が必要となります。 中身は同じなのに面倒くさいですね。そこで登場するのが関数のテンプレート機能です。 まず、関数テンプレートの書き方ですが次のようにします。

template <typename MYTYPE> MYTYPE myfunction(MYTYPE data1, MYTYPE data2) { ... }

MYTYPEの所は自分で好きな名前にしてかまいません。この例ではMYTYPEのところに 任意のデータ型が来ます。しかし、最初のMYTYPEがint型であれば、他のMYTYPEのところも int型になります。もちろん

template <typename MYTYPE> char *yourfunction(int data1, MYTYPE data2, double data3)

というように戻り値や、引数に指定したデータ型が来ても問題ありません。

では、例題を見てみましょう。

// 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数を比較して、大きい方のデータを返すプログラムです。 2数が等しいときは0を返します。どのような結果が出るか予想してみてください。 「粂井」と「田中」の比較はchar型へのポインタの比較となります。 その時のシステムの状況で結果が異なる可能性があります。

さて、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; }

どのような結果になるでしょうか。実験してみてください。

さて、少し古い本には次のような書き方をしているものもあります。

template <class X> char *func(X x, X y)

古いコンパイラでtypenameがサポートされていない場合はこのキーワードの代わりに classを使います。または、typenameをdefineしてしまってもよいでしょう。

#define typename class

の一文をソースファイルの最初に書いておきます。

さて、関数テンプレートがあるのだから、クラステンプレートもあるのだろうと 予想されます。実際にあります。次回はクラステンプレートをやります。


[C++Index] [総合Index] [Previous Chapter] [Next Chapter]

Update Jun/20/2000 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。