第36章 特注の鋳型

 関数テンプレートは丁度オーバーロード関数を大量生産するようなものです。では、関数テンプレートをオーバーロードすることはできるのでしょうか?


 では、今回の要点です。


 では、いってみましょう。


 Max に文字列を入れたとします。すると、TYPE は char* か const char* になるでしょう。そして、a > b はアドレスの比較になり、返ってくるのは a と b の保持しているアドレスのうち大きな方になります。

 この結果は当たり前のことではあるのですが、文字列を入れたときは文字列の内容を比較して欲しいものです。

 このように、何でもかんでも同じ鋳型から作っているだけでは困ることもあります。こういうときのために、特定のテンプレート引数に対して、特別な実装を使用することができます。

 ここでは TYPE が char* か const char* の時に strcmp で比較するようにすればいいのですね。そういうときは、

#include <string.h>

// 文字列用の Max (char* 用)
template < >
inline char* Max<char*>(char* a, char* b)
{
    return (strcmp(a, b) > 0) ? a : b;
}

// 文字列用の Max (const char* 用)
template < >
inline const char* Max<const char*>(const char* a, const char* b)
{
    return (strcmp(a, b) > 0) ? a : b;
}

のようにします。

 先ず先頭に template < > を付けます。そして、途中に明示的呼び出し(第34章参照)のようにテンプレート引数を指定します。それ以外は普通の実装と同じです。(注:古いコンパイラでは普通の定義と同じにしないといけないことがあります。)

 このようにすれば、Max で文字列の比較ができるようになります。

プログラム
// Temp5.cpp
#include <iostream.h>

// Max の定義は省略

int main()
{
    // str[1] は str[0] よりもアドレスは大きい
    char str[][32] = {
        "This is a pen.", "This is a book."
    };

    // Max<char*> が呼ばれます
    cout << Max(str[0], str[1]) << endl;

    // Max<const char*> で呼びます
    cout << Max<const char*>(str[0], "This is a zoo.") << endl;

    return 0;
}
実行結果
This is a pen.
This is a zoo.

 はい。きちんと文字列で比較できました。

 このように、テンプレートで特定の型に対して特別な実装を定義することをオーバーライド(特殊化)と呼びます。既にある Max<char*> や Max<const char*> の定義を別の定義で置き換えるので、これはオーバーライドになります。

 

 最後に1つ注意することは、オーバーライドした Max<char*> や Max<const char*> はもはやテンプレートではないということです。インライン関数ならヘッダファイルに書きますが、普通の関数ならヘッダファイルに書いてはいけません。


 それでは、今回の要点です。


 次回もテンプレートですが、ちょっと違うことをします。それでは、また。


第35章 冶金工場5 | 第37章 テンプレートクラス

Last update was done on 2000.12.6

この講座の著作権はロベールが保有しています