C++のテンプレートと静的変数の仕組みを徹底解説
この記事では、C++におけるテンプレート(template)と静的変数(static変数)がどのように相互作用するのかを、具体的なサンプルコードを通して解説します。
重要なポイント:テンプレートの各インスタンスは独立している
C++では、関数テンプレートやクラステンプレートを実体化すると、型ごとに独立したインスタンスが生成されます。そのため、テンプレート内で宣言されたstatic変数も、各インスタンスがそれぞれ独自のローカルコピーを持つことになります。これはC++プログラミングにおいて非常に重要な挙動です。
サンプルコード
#include <iostream>
using namespace std;
template <typename T>
void fun(const T& x) {
static int i = 10;
cout << ++i;
return;
}
int main() {
fun<int>(1); // 11 を出力
cout << endl;
fun<int>(2); // 12 を出力
cout << endl;
fun<double>(1.1); // 再び 11 を出力
cout << endl;
getchar();
return 0;
}実行結果
11 12 11
コードの解説
このプログラムの出力結果には、テンプレートとstatic変数の重要な特徴が表れています。
1回目・2回目の呼び出し: fun<int> は同じ int 型のインスタンスであるため、内部のstatic変数 i は共有された同一の変数です。1回目の呼び出しで i が10から11にインクリメントされ、2回目の呼び出しではその値が保持されたまま12になります。
3回目の呼び出し: fun<double> は double 型として新しく実体化された別のインスタンスです。そのため、static変数 i も新たに生成され、初期値10からカウントが始まり、再び11が出力されます。
まとめ
テンプレート内のstatic変数は「テンプレート全体で1つ」ではなく、「実体化された型ごとに1つずつ」存在します。この挙動を理解しておくと、型ごとに独立したカウンタやキャッシュなどをテンプレート関数・クラステンプレート内で安全に実装できるようになります。クラステンプレートのstaticメンバ変数についても同様に、型ごとに別々の実体が生成される点に注意してください。
-
C++で円と長方形の重なりを判定するアルゴリズム
問題の概要円を (radius, xc, yc) という形式で表します。ここで (xc, yc) は円の中心座標です。同様に、軸に平行な長方形(軸平行境界ボックス)を (x1, y1, x2, y2) という形式で表し、(x1, y1) が左下隅の座標、(x2, y2) が右上隅の座標とします。このとき、円と長方形が互いに重なっているかどうかを判定する必要があります。たとえば、次のような入力が与えられた場合を考えてみましょう。この場合、出力は true(重なりあり)となります。解決のアプローチこの問題を解く鍵は、「長方形の中で円の中心に最も近い点」を見つけることです。その点と円の中心との距離が
-
C++で解くドミノとトロミノを使ったタイル敷き詰め問題(2×Nボード)
問題の概要本記事では、「ドミノ」と「トロミノ」という2種類の形状を使ったタイル敷き詰め(タイリング)問題をC++で解く方法を解説します。これらのピースは、以下のように回転させて使用することができます。タイリングでは、盤面上のすべてのマスを必ずタイルで覆わなければなりません。また、2つのタイリング方法は、盤上の4方向に隣接する2つのセルにおいて、片方のタイリングだけがその両方のマスを同じタイルで占有している場合に限り「異なる」とみなされます。入力と出力の例整数Nが与えられたとき、2×Nのボードを敷き詰める方法が何通りあるかを求めます。例えば、入力が3の場合、出力は5となります。敷き詰め方は以下の