61

MSDN、無名構造体は C++ では非標準であると考えています。

Microsoft C 拡張機能を使用すると、名前を付けずに、別の構造内で構造変数を宣言できます。これらのネストされた構造は、無名構造と呼ばれます。C++ では無名構造を使用できません。

匿名構造体のメンバーには、それを含む構造体のメンバーであるかのようにアクセスできます。

@K-ballo同意します。

この機能は、名前のない構造体を作成することと必ずしも同じではないと言われていますが、標準的な言葉遣いに関しては違いがわかりません。

C++11 は次のように述べています。

[C++11: 9/1]: [..] class-headclass-head-nameを省略したclass -specifierは、名前のないクラスを定義します。

名前が欠落している型定義の文法構造全体を提供します。

C++03 にはこの明示的な表現がありませんが、同様にidentifier型定義の がオプションであることを示し、 および の「名前のないクラス」を参照し9.4.2/5ます3.5/4

  • では、MSDN は間違っていますか? これらはすべて完全に標準的なものなのでしょうか?
  • または、「名前のない構造体/クラス」と、この C++03/C++11 機能によってカバーされないようにするメンバーとして使用された場合との間に欠けている微妙な点がありますか?
  • 「名前のない構造体」と「匿名の構造体」の基本的な違いが欠けていますか? それらは私には同義語のように見えます。
4

3 に答える 3

64

すべての標準テキストは、「名前のない構造体」の作成に言及しています。

struct {
   int hi;
   int bye;
};

わかりやすい名前がなく、とてもフレンドリーなタイプです。

標準的な方法では、次のようなメンバーとしてインスタンス化できます。

struct Foo {
   struct {
      int hi;
      int bye;
   } bar;
};

int main()
{
   Foo f;
   f.bar.hi = 3;
}

ただし、「匿名の構造体」は微妙に異なります。これは、「名前のない構造体」と、親オブジェクトで魔法のようにメンバーを取得するという事実の組み合わせです。

struct Foo {
   struct {
      int hi;
      int bye;
   }; // <--- no member name!
};

int main()
{
   Foo f;
   f.hi = 3;
}

直感とは逆に、これは、ネストされたwitinである名前のない構造体を作成するだけでなくFoo、親オブジェクト内でメンバーにアクセスできるようにする一種の「匿名メンバー」を自動的に提供します。

非標準であるのはこの機能です。GCCそれをサポートしており、VisualC++もサポートしています。#define NONAMELESSUNIONWindows APIヘッダーはデフォルトでこの機能を利用しますが、Windowsヘッダーファイルをインクルードする前に追加することで、この機能を不要に指定できます。

同様のことを行う「匿名ユニオン」の標準機能と比較してください。

struct Foo {
   union {
      int hi;
      int bye;
   }; // <--- no member name!
};

int main()
{
   Foo f;
   f.hi = 3;
}

「名前なし」という用語はタイプ(つまり「クラス」または「構造体」)自体を指しますが、「匿名」という用語は代わりに実際のインスタンス化されたメンバーを指します(「構造体」の古い意味を使用) 「これは「 structy型のオブジェクト」に近い)。これが最初の混乱の原因だった可能性があります。

于 2013-01-09T23:09:01.877 に答える
14

Microsoftが匿名構造体と呼ぶものは標準ではありません。名前のない構造体は、名前のない通常の構造体です。そのタイプのオブジェクトも定義しない限り、1つでできることはあまりありません。

struct {
    int i;
    double d;
} my_object;

my_object.d = 2.3;

匿名ユニオンは標準の一部であり、 Microsoftの匿名構造体の説明を読むことで期待できる動作をします。

union {
    int i;
    double d;
};

d = 2.3;
于 2013-01-09T23:07:17.870 に答える
9

標準は無名共用体について述べています : [9.5]/5

フォームのユニオン

union { member-specification } ;

匿名組合と呼ばれます。名前のない型の名前のないオブジェクトを定義します。匿名共用体のメンバー仕様は、非静的データ メンバーのみを定義する必要があります。[ 注: ネストされた型と関数は、無名共用体内で宣言できません。—終わりの注] 匿名共用体のメンバーの名前は、匿名共用体が宣言されているスコープ内の他のエンティティーの名前とは区別されなければなりません。名前検索の目的で、匿名共用体の定義の後、匿名共用体のメンバーは、匿名共用体が宣言されているスコープで定義されていると見なされます。[ 例:

void f() {
    union { int a; const char* p; };
    a = 1;
    p = "Jennifer";
}

ここで、a と p は通常の (非メンバー) 変数のように使用されますが、それらは共用体メンバーであるため、同じアドレスを持ちます。—終わりの例]

マイクロソフトが話している匿名構造体は、この機能ですがに適用されます。名前のない定義だけでなく、匿名の共用体/構造体のメンバーは、匿名の共用体/構造体が宣言されているスコープで定義されていると見なされることに注意することが重要です。unionsstructs

私の知る限り、標準の名前のない構造体にはそのような動作はありません。引用された例では、スタック内の変数のストレージを共有するなど、他の方法では不可能なことをどのように達成できるかに注意してください。匿名の構造体はテーブルに新しいものをもたらしません。

于 2013-01-09T23:09:41.020 に答える