| Level 3:関数 3.7 関数テンプレート |
※資料は自著より引用
■3.7 関数テンプレート
●テンプレートテクニック
次のソースコードで定義されている引数付きマクロ mySortTemplate( T ) は,T型要素の配列を
整列できる関数 mySort( ) の定義を展開するように作成されている(9〜28行目)。
この引数付きマクロ mySortTemplate( T ) は,
あらかじめ特定の要素型の配列を第1引数を受け
取る関数 mySort( ) のオーバロードバージョンの定義をマクロ展開しておくことである。
・
30行目では, mySortTemplate( int ) として,第1引数に int型配列を受け取る
関数 void mySort( int a[ ], size_t element_num, ::sortFlag flag ); の定義をマクロ展開している。
・
31行目では, mySortTemplate( double ) として,第1引数に double型配列を受け取る
関数 void mySort( double a[ ], size_t element_num, ::sortFlag flag ); の定義をマクロ展開している。
そうして,その関数の必要なオーバロードバージョンの定義をマクロ展開しておき,それを呼び出して
いる(45,46,53,54行目)。
・マクロ定義による関数定義の一元化 sort4.cpp
●マクロ展開によるテンプレートテクニックの利点と欠点
●関数テンプレート

・関数テンプレートを利用した例 sort5.cpp


●関数テンプレートの仕組み
ソースコードはこちら。 クリックして画像が切り替えられます。

授業内練習問題:※リファレンスとテンプレートを個別に使った課題はこちら
上図で例に挙げた2つの引数の値を交換するテンプレート関数 mySwap( ) を,ポインタで引数を受け取る形ではなく,
リファレンスで引数を受け取る様に改良せよ。mySwap1.cpp
#include <iostream>
using namespace std;
template< class T > void mySwap( /* ここを完成させよ */ ) {
T temp = a;
a = b; b = temp;
}
int main( void ) {
int x = 10, y = 20;
mySwap( x, y );
cout << "x is " << x << endl << "y is " << y << endl;
double dx = 100.0, dy = 200.0;
mySwap( dx, dy );
cout << "dx is " << dx << endl << "dy is " << dy << endl;
char c; cin >> c; // 1文字タイプしてエンターキー
return 0;
}
●関数テンプレートの注意点
注意点1:複数の異なるテンプレート仮引数を使用できる。
以下は,二つの実引数のデータサイズを比較して第1実引数のサイズの方が大きいときは1を返し,
そうでない場合は0を返す関数 greater( ) の定義例。テンプレート関数の定義部分で,
< class T1, class T2 > というように,2つのテンプレート仮引数T1とT2が宣言されている。
#include <iostream>
#include <cstdlib>
using namespace std;
// 第1実引数のバイトサイズ > 第2実引数のバイトサイズ の場合 1 を返し,
// そうでないなら 0 を返す関数 greater( )。
template< class T1, class T2 >
bool greater( const T1 & a, const T2 & b ) {
return sizeof( a ) > sizeof( b );
}
int main( void ) {
int i; short s; double d;
cout << greater( i, d ) << endl; // 0 と表示。bool greater( const int & a, const double & b ); の定義が自動生成されて使われる。
cout << greater( i, s ) << endl; // 1 と表示。bool greater( const int & a, const short & b ); の定義が自動生成されて使われる。
char c; cin >> c; // 1文字タイプしてエンターキー
return 0;
}
注意点2:テンプレート
仮引数は返値型にも使用できる(ただし,関数仮引数にテンプレート仮引数を組み込んでおくこと)。#include <iostream>
using namespace std;
template< class T >
T maxElement( const T a[ ], size_t num ) {
T max = a[ 0 ];
for( size_t i = 1; i < num; i++ ) {
if( a[ i ] > max ) max = a[ i ];
}
return max;
}
int main( void ) {
int ia[ ] = { -10, 2, 4, 51, -100, 17 };
double da[ ] = { -123.0, 2.0, 4.0, 27.0, 7.0 };
cout << maxElement( ia, 6 ) << endl; // 51 と表示。 int maxElement( int a[ ], size_t num ); の定義が自動生成されて使われる。
cout << maxElement( da, 5 ) << endl; // 27 と表示。 double maxElement( double a[ ], size_t num ); の定義が自動生成されて使われる。
char c; cin >> c; // 1文字タイプしてエンターキー
return 0;
}