31

static constメンバーがローカル クラスに存在できない理由は何ですか? かなりばかげた制限のようです。

例:

void foo() {
  struct bar {
    int baz() { return 0; }   // allowed
    static const int qux = 0; // not allowed?!?
  };
}

struct non_local_bar {
  int baz() { return 0; }   // allowed
  static const int qux = 0; // allowed
};

標準 (9.8.4) からの引用:

ローカル クラスには、静的データ メンバーがあってはなりません。

4

4 に答える 4

27

標準セクション 9.4.2 から:

静的データ メンバーが const 整数型または const 列挙型の場合、クラス定義でのその宣言は、整数定数式である定数初期化子を指定できます。その場合、メンバーはそのスコープ内の整数定数式に表示できます。メンバーがプログラムで使用され、名前空間スコープ定義に初期化子が含まれていない場合、メンバーは名前空間スコープで定義されます。

基本的に、ローカル クラスにはリンケージがなく、静的データ メンバーにはリンケージが必要です。

名前空間スコープでローカル クラスの静的データ メンバーを定義する方法がないため (初期化子を使用した宣言は定義ではありません)、const 整数型であるかどうかにかかわらず、それらは許可されません。表面的には、コンパイラは値をインライン化できるように見えるかもしれませんが、メンバへのポインタにアクセスしようとするとどうなるでしょうか? 名前空間スコープのクラスを使用すると、リンカー エラーが発生するだけですが、ローカル クラスにはリンケージがありません。

理論的には、整数定数式でのみ使用される限り、ローカルクラスで static const 整数型を使用できるようにすることができると思いますが、おそらく標準化団体とコンパイラベンダーに負担をかけすぎて区別することはできません。実用的な価値はほとんどありません。ローカル静的変数はローカル クラスからアクセスできるため、ローカル静的 const を使用することも同様に適切です。

于 2011-11-17T07:07:20.257 に答える
5

理由があるとは思いません。通常の静的データメンバーは、宣言後に定義する方法がないため、許可されていません。

また、値を読み取るだけである限り (つまり、.its.address を使用しない限り)、クラス内で使用できるローカル const 変数を .class の外に作成できることも忘れないでください。

于 2011-11-17T06:34:34.137 に答える
3

クラスの静的メンバーは、グローバル スコープで定義する必要があります。

  abc.h

   class myClass {
   static int number;
  };
     abc.cpp

   int myClass::number = 314;

現在、void abc(int x) 内のスコープはグローバルではないため、静的メンバーを定義するスコープはありません。

于 2011-11-17T06:33:23.483 に答える
-1

物事が進むにつれて、C++ 11 が用意され、クラスで整数定数変数メンバーを定義できるようになりました。

class test
{
public:
    const int FOO = 123;

    [...snip...]
};

これは、C++11 でコンパイルすると機能します。staticキーワードが使用されていないことに注意してください。最適化をオンにしてコンパイルすると、これらの変数はすべて最適化されてしまう可能性があります。ただし、デバッグでは、それらは通常の変数メンバーとして構造体に表示されます。

ただし、クラス/構造体のサイズにはその変数が含まれることに注意してください。したがって、ここでは、変数 FOO に対して 4 バイトである可能性があります。

ただし、ほとんどの場合、関数で定義されたクラスは完全に最適化されるため、これは優れた方法です (私のクラスのかなりの 50% がそのような変数メンバーを持っています!)

于 2014-05-15T08:26:44.180 に答える