1. ホーム
  2. c++

[解決済み] クラス定義における static const integer メンバの定義

2022-09-15 12:43:07

質問

C++では、整数型であればクラス内部でstatic constメンバを定義することができると理解しています。

では、なぜ次のコードはリンカーエラーを引き起こすのでしょうか?

#include <algorithm>
#include <iostream>

class test
{
public:
    static const int N = 10;
};

int main()
{
    std::cout << test::N << "\n";
    std::min(9, test::N);
}

というエラーが出ます。

test.cpp:(.text+0x130): undefined reference to `test::N'
collect2: ld returned 1 exit status

興味深いことに、std::minの呼び出しをコメントアウトすると、コードはうまくコンパイルされリンクされます(たとえtest::Nが前の行で参照されていたとしても)。

何が起こっているのかについて、何か考えはありますか?

私のコンパイラは、Linux上のgcc 4.4です。

どのように解決するのですか?

私の理解では、C++は整数型である限り、クラス内部でstatic constメンバを定義することができます。

あなたはある意味正しいです。 クラス宣言で静的定数積分を初期化することは許されていますが、それは定義ではありません。

興味深いことに、std::minへの呼び出しをコメントアウトすると、コードは(test::Nが前の行でも参照されているにもかかわらず)うまくコンパイルおよびリンクされます。

何が起こっているのかについて、何か考えはありますか?

std::minはconst参照によってそのパラメータを取ります。 もし値で受け取るのであれば、この問題は発生しませんが、参照が必要なので、定義も必要です。

以下は章/節です。

9.4.2/4 - もし static のデータメンバは const 積分または const 列挙型の場合、クラス定義でその宣言に 定数初期化子 を指定することができる。これは,積分定数式でなければならない(5.19)。 この場合,メンバは,積分定数式に現れることができる。 そのメンバがプログラム中で使用される場合も,名前空間スコープで定義しなければならず,名前空間スコープの定義に 初期化子 .

可能な回避策については、Chuさんの回答を参照してください。