テンプレート_(プログラミング)
[Wikipedia|▼Menu]
.mw-parser-output .hatnote{margin:0.5em 0;padding:3px 2em;background-color:transparent;border-bottom:1px solid #a2a9b1;font-size:90%}

この項目では、主にC++の言語仕様について説明しています。

入力と雛形に基づいてデータを出力するソフトウェアについては「テンプレートエンジン」をご覧ください。

特にウェブページにおけるテンプレートエンジンについては「Webテンプレート」をご覧ください。

使用頻度の高いコードの断片については「スニペット」をご覧ください。

プログラミングにおけるテンプレートは、静的型付けプログラミング言語データ型を抽象化してコードを書くことを可能にする機能であり、C++D言語においてはジェネリックプログラミングに用いられる。

C++のテンプレートは後から追加された機能だが、多重継承演算子多重定義と並ぶ重要な機能となった。STL (Standard Template Library) はテンプレートによって構築された汎用的なアルゴリズムやデータ構造を含むソフトウェアフレームワークとなっている。
C++
概要

C++11規格までのテンプレートには、大別して関数テンプレートとクラステンプレートがある。C++14では変数テンプレートもサポートするようになった。

関数テンプレートは任意の型の引数を受け取ることができる関数のようなものである。たとえば、標準C++ライブラリにある関数テンプレートmax(x, y)は引数xとyのうち、大きな方を返す関数テンプレートで、次のように定義できる。template <typename T>const T& max(const T& x, const T& y){ if (x < y) return y; else return x;}

そして次のように呼び出せる。using namespace std;cout << max<int>(3, 7) << endl; // 7が出力される。cout << max(3, 7) << endl; // max(int, int) から max<int>(const int&, const int&) に推論される。cout << max(3, 7L) << endl; // int, long の曖昧さが解決できないためコンパイルエラー。cout << max<double>(-3.1, -8) << endl; // -3.1が出力される。cout << max(-3.1, -8.0) << endl; // max(double, double) から max<double>(const double&, const double&) に推論される。cout << max(-3.1, -8) << endl; // double, int の曖昧さが解決できないためコンパイルエラー。

ここで、テンプレート内にてTで表されているものをテンプレート仮引数 (template parameter) という。Tはパラメータ化された型 (parameterized type) とも呼ばれる。テンプレート仮引数はtypenameキーワードもしくはclassキーワードを用いて修飾する必要がある。テンプレート自身は実体をもたないため、利用する際は実体化 (instantiate) する必要がある。実体化の方法のひとつとして、max<int>のように具体的な型すなわちテンプレート実引数 (template argument) を明示的に指定することができるが、曖昧さがない場合に限り、コンパイラは関数テンプレートの実引数として与えられた値の型(この例の場合では、xおよびyとして渡された整数型リテラルの型であるint)からTに対応する型を推論し、得られた具体的な型intをTに当てはめて関数を暗黙的に実体化することもできる。このようにして実体化された関数を特殊化(あるいは特殊化版、特殊バージョン)という。例のmax<int>(3, 7), max(3, 7)に対してはintの特殊化が、max<double>(-3.1, -8), max(-3.1, -8.0)に対してはdoubleの特殊化が呼ばれることになる。なお、実体化のことを具現化と呼ぶこともある。

maxのインスタンス化に際して、xとyがどんな型でもx < yという式が生成される。またユーザー定義型の場合も、<演算子が適切に多重定義されていればその型に対してmaxが使える。Tとして利用可能な型の集合に何らかの共通の継承関係がある必要はない。つまり、テンプレートは静的なダック・タイピング (duck typing) を可能とする。同様の例は他にもあり、STLには適切な演算子が定義されていれば任意の型が利用可能になるという関数テンプレートが数多く存在する。例えば<演算子が定義されていれば、sort(), stable_sort(), binary_search()や、配列からヒープ構造を作成するアルゴリズム[要説明]、setなどのコンテナなどが利用可能になる。関数テンプレートには述語 (predicate) として関数オブジェクトを受け取るものも存在し、ソートの比較などに使われるコールバック関数をカスタマイズすることが容易になっている。つまり、要件を満たすためのいくつかの演算子を定義するだけで、新しいデータ型に対して幅広い機能を得られる。

C++のテンプレートは完全にコンパイル時点でタイプセーフである。例えば、複素数には狭義の順序 (strict order) がないので、標準C++ライブラリの複素数型であるcomplexには<演算子が定義されていない。従って、前述のmax関数テンプレートにcomplex型を指定した場合、コンパイルエラーとなる。同様に、<をあてにする他のテンプレートはcomplexデータに適用できない。ただ、通例コンパイラはこの種のエラーに対して、難解でほとんど役に立たないエラーメッセージを出力する。テンプレートが関わるエラーを出さないように、プログラマーは利用する関数テンプレートの仕様をあらかじめよく確認しておくしかない。

一般的に、そのようなテンプレート実引数に対する要求は、コンセプト (concept) や要件 (requirement) などとして別途文書によって記述されている。標準C++ライブラリのstd::max関数テンプレート (X3014 25.3.7) では、そのテンプレート実引数がLessThanComparableでなければならないと定められている。ある型がLessThanComparableであるためには、正にa < bという演算ができなければならない (X3014 20.1.2) と定められているのである。

テンプレートに関するコンパイルエラーメッセージを改善するために、C++0xではコンセプトと呼ばれる機能の導入が検討されていたが、結局C++11では見送られた。コンセプトはC++17規格でも実装されていない。

クラステンプレートはテンプレートの概念をクラスに当てはめたものである。汎用的なコンテナ (generic containers) の作成によく用いられる。たとえばSTLにはリンクリストとしてstd::listが存在する。整数のリストを作りたければstd::list<int>と書き、文字列のリストを作りたければstd::list<std::string>と書けばよい。std::listの要素型に対する要件は規格バージョンによって異なるが、例えばC++03まではCopyAssignableおよびCopyConstructibleを必要とする[1]。これらの要件を満たす限り、たとえどんな型がstd::listの要素型として指定されても動作する共通の関数集合が定義されている。なお、関数テンプレートと違い、クラステンプレートではテンプレート引数を型推論することができなかったが、C++17にてサポートされるようになった。


次ページ
記事の検索
おまかせリスト
▼オプションを表示
ブックマーク登録
mixiチェック!
Twitterに投稿
オプション/リンク一覧
話題のニュース
列車運行情報
暇つぶしWikipedia

Size:22 KB
出典: フリー百科事典『ウィキペディア(Wikipedia)
担当:undef