C++ 標準では (9.4.2 節 4 節)、整数型または列挙型の静的メンバー変数はクラス内で初期化子を提供できるが、これにはクラス外 (コンパイル ユニット内) でそのメンバーの定義が必要であることがわかっています。 )。つまり、次のようなことをする必要があります。
class A
{
public:
static const int X = 10;
};
// this is required by the standard
const int A::X;
一部のコンパイラでは、クラス外の定義がなくても問題なく処理できることがわかりました (他の場所でも述べられています)。これは、OS X の gcc 4.2.1 で動作します。
#include <iostream>
class A
{
public:
static const int X = 10;
};
int main(int argc, char** argv)
{
std::cout << A::X << std::endl;
return 0;
}
私は最近、誰かがこれを行ったというバグに遭遇しましたが、彼らはテンプレート化された関数内でメンバー変数を使用していました (std::max
正確には)、未定義のシンボル A::XIe について不平を言い、コンパイルされませんでした。これは機能しません:
#include <iostream>
#include <algorithm>
class A
{
public:
static const int X = 10;
};
int main(int argc, char** argv)
{
std::cout << std::max(1, A::X) << std::endl;
return 0;
}
クラス外の定義を追加し直すと、機能します。
これは一種の学術的な質問ですが、なぜこのようなことが起こるのか知りたいです。特に、静的メンバー変数を静的関数 ( become 、 become ) に置き換えると、クラス外の定義なしでコンパイルされるという事実に関連してstatic const int X = 10;
。テンプレートに言及する理由は、がテンプレート化されており、他のテンプレート化された関数が同じ動作を再現するためです。テンプレートに特に関連しているわけではないかもしれませんが、テンプレートがその動作を引き起こす理由を理解したいと思います。これは、テンプレートと静的メンバーがコンパイル/実装される方法に関係していると思いますか?static int X()
A::X
A::X()
std::max
PS - 最小限のコードをgithubに投稿しました