ボレロ村上 - ENiyGmaA Code

中3女子です。

static データメンバの初期化 - constexpr な場合とそうでない場合


constexpr の間違った使い方。 - C++でゲームプログラミング
この記事へのフォローです。


constexpr static データメンバの場合は、"コンパイル時定数である変数は、宣言と同時に初期化しなければならない" という原則にしたがって、
クラススコープの内側に初期化を書いてやります。

template<typename T>
struct X {
    static constexpr T value = {};
};

template<typename T>
constexpr T X<T>::value;


つまり、constexpr の場合は内側の宣言に初期化を書き、そうでない場合は外側に初期化を書かなければならない。
非常に面倒な仕様と思います。


なお Sprout C++ Library では、constexpr が使える場合とそうでない場合双方に対応するために、
SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_INNER および SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_OUTER という二つのマクロを使っています。

//#define SPROUT_CONFIG_DISABLE_CONSTEXPR /* constexpr を無効にするかどうかのオプション。通常はコンパイラに応じて自動的に定義される */
#include <sprout/config.hpp>

template<typename T>
struct X {
    SPROUT_STATIC_CONSTEXPR T value
    SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_INNER({}); // constexpr が有効な場合はこちらで初期化される
};

template<typename T>
SPROUT_CONSTEXPR_OR_CONST T X<T>::value
SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_OUTER({});     // constexpr が無効な場合はこちらで初期化される


見てのとおり非常に面倒です。
C++03コンパイラ をターゲットにしなくてよい開発ならば、全部 constexpr で統一すればよいと思います。


Ceterum autem censeo, VC++ esse delendam. (ともあれ、VC++は滅ぶべきであると考える次第である)