最近ヘッダーファイルでこのコードを見ましたが、それが機能することに驚きました:
namespace NS {
static int uid = 0;
class X {
public:
static int getUID() { return uid++; }
};
}
静的メソッドNS::X::getUID()
が複数の異なる C++ ソース ファイルから呼び出された場合、一意の ID (翻訳単位全体で一意) が正しく生成されたことに驚きました。名前空間スコープの静的変数には、翻訳単位への内部リンケージがあると思いました。何が起きてる?クラス X のインライン静的メソッドには独自の翻訳単位があり、それが一意の ID を生成する理由ですか? または、コンパイラの癖が原因で機能していますか?
上記のコードは、「安全な」明確に定義された動作に依存していますか? もしそうなら、これはインラインまたはテンプレート クラスで一意の ID を生成する驚くほど簡潔な方法です。それとも、このような静的一意 ID 関数の新しい C++ ソース ファイルを生成し、静的 ID をクラス内に移動する方がよいでしょうか?
アップデート:
テスト ケースとして、次のようないくつかの関数を異なるファイル (file1.cpp、file2.cpp など) に記述しました。
#include "static_def.h" // Name of the above header file.
void func1() {
int uid1 = NS::X::getUID();
int uid2 = NS::X::getUID();
std::cout << "File1, UID1: " << uid1 << ", UID2: " << uid2 << std::endl;
}
驚くべき出力 (これらを main から呼び出した後) は次のとおりです。
File1, UID1: 0, UID2: 1
File2, UID1: 2, UID2: 3