C++テンプレート完全ガイド:ジェネリックプログラミングの基礎
テンプレートはジェネリックプログラミングの基盤であり、特定の型に依存しない方法でコードを記述することを含みます。
テンプレートは、ジェネリックなクラスや関数を作成するための設計図または公式です。イテレータやアルゴリズムのようなライブラリコンテナは、ジェネリックプログラミングの例であり、テンプレート概念を使用して開発されています。
vector のような各コンテナには単一の定義しかありませんが、例えば vector <int> や vector <string> のように、さまざまな種類のベクトルを定義できます。
テンプレートを使用して関数とクラスの両方を定義できます。それらがどのように機能するか見てみましょう:
関数テンプレート
テンプレート関数定義の一般的な形式:
template <class type> ret-type func-name(parameter list) {
// 関数本体
}
ここで、type は関数で使用されるデータ型のプレースホルダ名です。この名前は関数定義内で使用できます。
2つの値の最大値を返す関数テンプレートの例:
Live Demo#include <iostream>
#include <string>
using namespace std;
template <typename T>
inline T const& Max (T const& a, T const& b) {
return a < b ? b:a;
}
int main () {
int i = 39;
int j = 20;
cout << "Max(i, j): " << Max(i, j) << endl;
double f1 = 13.5;
double f2 = 20.7;
cout << "Max(f1, f2): " << Max(f1, f2) << endl;
string s1 = "Hello";
string s2 = "World";
cout << "Max(s1, s2): " << Max(s1, s2) << endl;
return 0;
}
上記コードをコンパイルして実行すると、以下の結果が得られます:
Max(i, j): 39 Max(f1, f2): 20.7 Max(s1, s2): World
クラステンプレート
関数テンプレートを定義できるのと同様に、クラステンプレートも定義できます。ジェネリッククラス宣言の一般的な形式:
template <class type> class class-name {
. . .
}
ここで、type はクラスがインスタンス化されるときに指定されるプレースホルダ型名です。カンマ区切りのリストを使用して、複数のジェネリックデータ型を定義できます。
Stack<> クラスを定義し、スタックから要素をプッシュ/ポップするジェネリックメソッドを実装する例:
Live Demo#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>
using namespace std;
template <class T>
class Stack {
private:
vector<T> elems; // 要素
public:
void push(T const&); // 要素をプッシュ
void pop(); // 要素をポップ
T top() const; // トップ要素を返す
bool empty() const {
// 空ならtrueを返す
return elems.empty();
}
};
template <class T>
void Stack<T>::push (T const& elem) {
// 渡された要素のコピーを追加
elems.push_back(elem);
}
template <class T>
void Stack<T>::pop () {
if (elems.empty()) {
throw out_of_range("Stack<>::pop(): empty stack");
}
// 最後の要素を削除
elems.pop_back();
}
template <class T>
T Stack<T>::top () const {
if (elems.empty()) {
throw out_of_range("Stack<>::top(): empty stack");
}
// 最後の要素のコピーを返す
return elems.back();
}
int main() {
try {
Stack<int> intStack; // intのスタック
Stack<string> stringStack; // stringのスタック
// intスタックを操作
intStack.push(7);
cout << intStack.top() << endl;
// stringスタックを操作
stringStack.push("hello");
cout << stringStack.top() << std::endl;
stringStack.pop();
stringStack.pop();
} catch (exception const& ex) {
cerr << "Exception: " << ex.what() << endl;
return -1;
}
}
上記コードをコンパイルして実行すると、以下の結果が得られます:
7 hello Exception: Stack<>::pop(): empty stack
C言語
- C++データ型完全ガイド:基本型、修飾子、ベストプラクティス
- C++演算子完全ガイド:算術・代入・関係・論理・ビット演算子と実例
- C++コメント完全ガイド:読みやすく保守しやすいコードのためのベストプラクティス
- C++コンストラクタ完全ガイド:デフォルト、パラメータ付き、コピーの違いと実例
- C++クラステンプレート完全ガイド:実践的なジェネリックプログラミング
- C++プログラミング言語:概要と主要機能
- C++定数とリテラル完全解説:型、構文、ベストプラクティス
- C++演算子完全ガイド:種類、使い方、ベストプラクティス
- C++数値型完全ガイド:実践的な使い方と数学関数
- C++リファレンス完全理解:重要概念とポインタとの違い
- C++プリプロセッサ完全解説:ディレクティブがコードをどう形作るか