2

私はVisual Studio 2010を使用していますが、このクラスがどのように間違っているのか(構文エラー:識別子 'EnumType')、コンパイルできません:

class BrokenClassWithEnum
{
private:
    void useEnum (EnumType enumType); //syntax error : identifier 'EnumType '
public:
    enum EnumType 
    {
        VAL1,
        VAL2,
        VAL3
    };
}

そして、これは問題ありません:

class WorkingClassWithEnum
{
public:
    enum EnumType 
    {
        VAL1,
        VAL2,
        VAL3
    };
private:
    void useEnum (EnumType enumType);
}

クラスのスコープはどうなりましたか?

4

4 に答える 4

5

定義の順序(宣言ではない)は重要ではないと思いますが、前方宣言はこのエラーを解決します-少なくともMSVC ++6では。MSVC++6以外では、列挙型を前方宣言するストレージタイプを指定する必要があります(前方列挙型のストレージタイプはC++0x標準でした)

注:VC ++ 6では、ストレージタイプを省略できますが、列挙型を前方宣言する場合は、ストレージタイプを宣言する必要があります(以下を参照)。

これにより、VC++6のエラーが解決されます。ただし、VC ++ 6は、C ++ 0x標準で要求されているように、クラス内の列挙型のSTORAGETYPEをサポートしていないようです。

class BrokenClassWithEnum {
public:
    enum EnumType;

private:
    void useEnum (EnumType enumType); 
public:
    enum EnumType {
        VAL1,
        VAL2,
        VAL3
    };
};


通常、C ++ 0x準拠のコンパイラ内のIEは、次のようなものを使用します。

class BrokenClassWithEnum {
public:
    enum EnumType : int;

private:
    void useEnum (EnumType enumType);
public:
    enum EnumType : int {
        VAL1,
        VAL2,
        VAL3
    };
};

注:列挙型の前方宣言は、すべてではありませんが一部のC++バージョンで可能です。

C++で列挙型を宣言するフォワード

于 2013-01-12T00:16:09.547 に答える
3

クラス定義自体の中で、アイテムは他のスコープと同じように順番に表示される必要があります(依存アイテムはそれらに依存するアイテムの前に表示されます)。クラスメソッド本体の内部(インライン化されている場合でも)では、クラスの定義全体を利用できます。

于 2013-01-12T00:16:37.263 に答える
3

C++ では、参照される非組み込みの名前は、以前のどこかで宣言されている必要があります。

以下が正常に機能するため、このルールにはクラス定義の例外があるように見える場合があります。

struct S
{
    void foo() { cout << x_ << endl; }
    int x_;
    S(): x_( 42 ) {}
};

ただし、使用前宣言に関する規則は、変換されたコードに適用されます。

struct S
{
    inline void foo();
    int x_;
    inline S();
};

void S::foo() { cout << x_ << endl; }
S::S() : x_( 42 ) {}

これは、コンパイラが「適切に」見るものです。ここでは、まだ宣言されていないものは使用されません。

問題に対する C++03 の適切な解決策は、最初に使用する前に列挙型を定義することです。C++11 では、代わりに前方宣言することもできますが、基になる型を指定する必要があります。

C++11 §7.2/3 :
不透明列挙宣言は、現在のスコープ内の列挙の再宣言か、新しい列挙の宣言のいずれかです。[注: opaque-enum-declarationによって宣言された列挙型は、基になる型が固定されており、完全な型です。列挙子のリストは、後で列挙指定子を使用して再宣言することで提供できます。—最後の注] スコープ付き列挙は、後でスコープなしとして、または別の基になる型で再宣言してはなりません。スコープのない列挙は、後でスコープ付きとして再宣言してはならず、各再宣言には、元の宣言と同じ基礎となる型を指定する列挙型ベースを含める必要があります。」

于 2013-01-12T01:35:29.923 に答える
-1

クラスの検証またはコンパイルは2回のパスで行われるため、クラス内の宣言の前にメンバー変数にアクセスできると思います。

于 2022-02-03T22:54:52.453 に答える