1. ホーム
  2. c++

[解決済み] C++でクラス宣言内のconstメンバの初期化

2023-05-27 08:37:49

質問

PHPやC#では、定数は宣言と同時に初期化することができます。

class Calendar3
{
    const int value1 = 12;
    const double value2 = 0.001;
}

次のようなC++のファンクタの宣言があります。これは、2つの数学ベクトルを比較するために別のクラスで使用されます。

struct equal_vec
{
    bool operator() (const Vector3D& a, const Vector3D& b) const
    {
        Vector3D dist = b - a;
        return ( dist.length2() <= tolerance );
    }

    static const float tolerance = 0.001;
};

このコードはg++で問題なくコンパイルできました。現在、C++0x モード (-std=c++0x) では、g++ コンパイラはエラーメッセージを出力します。

error: 'constexpr' needed for in-class initialization of static data member 'tolerance' of non-integral type

私はこれを定義して初期化することができることを知っています static const メンバをクラス定義の外部で定義することができます。また、非静的定数データメンバはコンストラクタのイニシャライザリストで初期化することができます。

しかし、PHPやC#で可能なように、クラス宣言内で定数を初期化する方法はあるのでしょうか?

更新

私は static キーワードを使用したのは、g++のクラス宣言の中でそのような定数を初期化することが可能だったからです。私はただ、クラス宣言の中で定数を初期化する方法が必要なのです。 static と宣言されているかどうかに関係なく、クラス宣言で定数を初期化する方法が必要です。

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

C++11では、非 static データメンバを static constexpr データ・メンバ、および static const のデータメンバは,クラス宣言で初期化することができます.

struct X {
    int i=5;
    const float f=3.12f;
    static const int j=42;
    static constexpr float g=9.5f;
};

この場合 i クラスのすべてのインスタンスのメンバ X に初期化されます。 5 に初期化され、コンパイラが生成したコンストラクタによって f に初期化されます。 3.12 . また static const データメンバ j は初期化され 42 であり、かつ static constexpr データメンバ g は初期化され 9.5 .

このため floatdouble が積分型や列挙型でない場合、そのようなメンバは必ず constexpr でなければならず、また非 static を使用することで、クラス定義のイニシャライザーが許可されます。

C++11 より前のバージョンでは static const のデータ メンバのみがクラス定義で初期化子を持つことができました。