41

次のコードの問題は、タイプ「constdouble」の静的メンバーがクラス内初期化子を持つことができないことです。次のコードの「constdouble」にのみ適用できるのはなぜですか?私を助けてください。

class sample{
   static const char mc = '?';
   static const double md = 2.2;
   static const bool mb = true;
};
const char sample::mc;
const double sample::md;
const bool sample::mb;
int main(){
}
4

3 に答える 3

61

C ++ 03言語標準によって実装されるロジックは、次の理論的根拠に基づいています。

C ++では、初期化子はオブジェクト定義の一部です。静的メンバーのクラス内に書き込むのは、実際には宣言のみです。したがって、正式に言えば、クラス内の静的メンバーに初期化子を指定することは「正しくありません」。これは、言語の一般的な宣言/定義の概念に反しています。クラス内で宣言する静的データは、いずれにせよ後で定義する必要があります。ここで、初期化子を指定する機会があります。

C ++のこのような定数は積分定数式(ICE)を形成できるため、この規則の例外は静的整数定数に対して行われました。ICEは言語で重要な役割を果たし、意図したとおりに機能するためには、積分定数の値がすべての変換単位で表示される必要があります。定数の値をすべての変換単位で表示するには、宣言の時点で表示する必要があります。これを実現するために、言語では初期化子をクラスで直接指定できます。

さらに、多くのハードウェアプラットフォームでは、定数整数オペランドをマシンコマンドに直接埋め込むことができます。または、定数を完全に削除または置換することもできます(たとえば、による乗算は、による8シフトとして実装できます3)。オペランドが埋め込まれたマシンコードの生成やさまざまな算術最適化を容易にするために、すべての変換単位で整数定数の値を表示することが重要です。

非整数型には、ICEのような機能はありません。また、ハードウェアプラットフォームでは、通常、非整数オペランドをマシンコマンドに直接埋め込むことはできません。このため、上記の「ルールからの例外」は非整数型には適用されません。それは単に何も達成しないでしょう。

于 2012-12-04T06:43:37.890 に答える
29

コンパイラは私に次constexprの代わりに使用するように提案しましたconst

static_consts.cpp:3:29: error: ‘constexpr’ needed for in-class initialization of static data member ‘const double sample::md’ of non-integral type [-fpermissive]
static_consts.cpp:7:22: error: ‘constexpr’ needed for in-class initialization of static data member ‘const double sample::md’ of non-integral type [-fpermissive]

私はちょうど申し出を受け入れました:

class sample{
   static const char mc = '?';
   static constexpr double md = 2.2;
   static const bool mb = true;
};
const char sample::mc;
const bool sample::mb;
int main(){
}

そして今、それはうまくコンパイルされます(C ++ 11)。

于 2016-03-15T11:47:48.797 に答える
13

C ++ 11より前では、クラス定義で直接初期化できるのはconst整数型のみでした。これは、標準によって課せられた単なる制限です。

C ++ 11では、これは適用されなくなりました。

于 2012-12-04T06:30:26.257 に答える