2015年07月12日

C++ メモランダム (template)

大相撲の名古屋場所が始まりました。いよいよ本格的な夏のスタートという気分です。

今日は全国的に真夏日ということで、名古屋も非常に暑い一日でした。熱射病や水の事故のニュースも流れていて、これから要注意ですね。台風の影響で大雨なんかにも気をつけたいところです。

-----

C++ の持つ機能の一つであるテンプレートの最も簡単な使い方として、任意の型に対して同じ処理を行うような場合にまとめて書いておくというものがあります。

template<class T> T sum( T t1, T t2 )
{ return( t1 + t2 ); }

型 T が和の演算子 ( + ) を使えるならどんな型でもこの関数が適用できます。特別バージョンを作りたければ

template<> SomeClass sum( SomeClass c1, SomeClass c2 )
{
SomeClass c = c1;
c.add( c2 );
return( c );
}

としておけば、引数が SomeClass の場合だけ下側が使われるようになります。

テンプレート関数は宣言だけしておくこともできます。例えば、sin の逆関数である asin は、float, double, long double 用に asinf, asin, asinl と関数名が分かれていますが、

template<class T> T Asin( T t );
template<> inline double Asin<double>( double t )
{ return( asin( t ) ); }
template<> inline long double Asin<long double>( long double t )
{ return( asinl( t ) ); }
template<> inline float Asin<float>( float t )
{ return( asinf( t ) ); }

としておけば、呼び出し側で型を変えても自動的に追随してくれます。特別バージョンだけ実装しておいても、他の型を利用しない限りはコンパイルできます。

ようやくテンプレートを上手に使いこなすための知識が身についてきて、様々なところで利用するようになってきました。やはり、問題になるのはエラーが出た時に内容が理解しづらいというところでしょうか。これも慣れるに従ってそれほど苦にはならなくなるものの、初めて見るようなエラーメッセージに対しては今でもしばらく悩むことがあります。
asin を float, double, long double でまとめて同じ関数名にする方法ですが、ヘッダファイルとして math.h ではなく cmath を指定すれば同名の関数が多重定義されているので、この方法は不要だったようです。やっぱり、便利なものはたいてい標準化されているんですね。

この記事へのトラックバックURL

http://fussy.mediacat-blog.jp/t110243
※このエントリーではブログ管理者の設定により、ブログ管理者に承認されるまでコメントは反映されません