テンプレートと標準テンプレートライブラリ(STL)は、C++プログラミングの中核を成す重要な要素です。これらを理解することで、再利用可能で効率的なコードを書きやすくなり、特に大規模プロジェクトにおいて強力なツールとなります。このガイドでは、テンプレートの基本からSTLの主要なコンポーネントまで、最新のC++の知識に基づいて詳しく解説します。
テンプレートの基礎
テンプレートは、関数やクラスを汎用化するために使用されるC++の機能です。これにより、特定のデータ型に依存せずに動作するコードを書くことができます。テンプレートは「関数テンプレート」と「クラステンプレート」の2つに大別されます。
関数テンプレート
関数テンプレートは、同じ処理を異なるデータ型に対して実行する関数を汎用的に定義する際に利用します。例えば、2つの値を比較して大きい方を返す関数をテンプレートとして定義する方法を見てみましょう。
#include <iostream>
using namespace std;
template <typename T>
T getMax(T a, T b) {
return (a > b) ? a : b;
}
int main() {
cout << getMax(10, 20) << endl; // int型
cout << getMax(10.5, 7.3) << endl; // double型
return 0;
}
このコードでは、getMax関数がテンプレートを利用して定義されています。typename Tは、任意のデータ型を受け取ることができる汎用的な型パラメータです。実行結果は以下の通りです。
20 10.5
クラステンプレート
クラステンプレートは、データ型に依存しないクラスを定義するために使用されます。これにより、複数のデータ型に対して同じロジックを適用できる柔軟なクラスを作成できます。以下の例では、スタックの動作をテンプレートとして実装しています。
#include <iostream>
using namespace std;
template <typename T>
class Stack {
private:
T arr[100];
int top;
public:
Stack() : top(-1) {}
void push(T val) {
if (top >= 99) {
cout << "Stack overflow" << endl;
} else {
arr[++top] = val;
}
}
void pop() {
if (top < 0) {
cout << "Stack underflow" << endl;
} else {
top--;
}
}
T peek() {
if (top < 0) {
cout << "Stack is empty" << endl;
return 0; // 仮の値を返す
} else {
return arr[top];
}
}
bool isEmpty() {
return (top < 0);
}
};
int main() {
Stack<int> intStack;
intStack.push(10);
intStack.push(20);
cout << intStack.peek() << endl; // 20
Stack<string> stringStack;
stringStack.push("Hello");
stringStack.push("World");
cout << stringStack.peek() << endl; // World
return 0;
}
このクラステンプレートでは、任意のデータ型のスタックを作成できます。整数のスタックと文字列のスタックの両方を生成し、pushおよびpeek操作を実行しています。
20 World
標準テンプレートライブラリ(STL)
標準テンプレートライブラリ(STL)は、C++の強力なライブラリであり、データ構造やアルゴリズムを提供します。STLは主に「コンテナ」、「イテレータ」、「アルゴリズム」の3つの要素で構成されています。
コンテナ
コンテナは、データを格納し、操作するためのクラスです。STLには、vector、list、mapなど、さまざまなコンテナが用意されています。以下は、vectorの使用例です。
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> vec;
vec.push_back(10);
vec.push_back(20);
vec.push_back(30);
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
cout << endl;
return 0;
}
この例では、vectorは可変長の配列のように動作し、データを動的に追加できます。実行結果は以下の通りです。
10 20 30
イテレータ
イテレータは、コンテナ内の要素にアクセスするためのオブジェクトです。ポインタのように動作し、コンテナ内を移動する際に使用されます。以下は、vectorのイテレータを使った例です。
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> vec = {10, 20, 30};
vector<int>::iterator it;
for (it = vec.begin(); it != vec.end(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}
この例では、begin()からend()までの範囲でイテレータを使って要素にアクセスしています。出力は次の通りです。
10 20 30
アルゴリズム
STLには、sortやfindなど、一般的な操作を効率的に実行するためのアルゴリズムが豊富に用意されています。これらは、コンテナに対して簡単に適用できます。以下は、sortを使った例です。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> vec = {30, 10, 20};
sort(vec.begin(), vec.end());
for (int i : vec) {
cout << i << " ";
}
cout << endl;
return 0;
}
この例では、sortアルゴリズムを使用して、vector内の要素を昇順に並べ替えています。実行結果は以下の通りです。
10 20 30
まとめ
テンプレートとSTLは、C++プログラミングにおいて非常に強力なツールです。テンプレートを使うことで汎用的なコードを書きやすくなり、STLを活用することで効率的にデータを操作できるようになります。この記事では、テンプレートとSTLの基本を学び、実際のコード例とともにその使い方を説明しました。さらに理解を深めるためには、実際に自分のプロジェクトでこれらの機能を試してみることをおすすめします。
