一部のC++コンパイラでは、匿名のユニオンと構造体を標準C++の拡張として許可しています。それは時折非常に役立つ構文糖衣のビットです。
これが標準の一部になるのを防ぐ理由は何ですか?技術的な障害はありますか?哲学的なものですか?それとも、それを正当化する必要性だけでは不十分ですか?
ここに私が話していることのサンプルがあります:
struct vector3 {
union {
struct {
float x;
float y;
float z;
};
float v[3];
};
};
私のコンパイラはこれを受け入れますが、 "nameless struct/union"はC++の非標準の拡張機能 であると警告します。
他の人が指摘したように、匿名の共用体は標準C++で許可されていますが、匿名の構造体は許可されていません。
これは、Cが匿名の共用体をサポートしているが匿名の構造体*をサポートしていないため、C++は互換性のために前者をサポートしますが、互換性のために必要ないため後者をサポートしないためです。
さらに、C++の匿名構造体にはあまり使用されません。 .v[i]
、または.x
、.y
、および.z
のいずれかで参照できる3つのフロートを含む構造体を使用するために、あなたが示す使用法は、未定義の結果になると信じていますC++での動作。 C++では、.v[1]
などのユニオンの1つのメンバーに書き込み、.y
などの別のメンバーから読み取ることはできません。これを行うコードは珍しくありませんが、実際には十分に定義されていません。
ユーザー定義型のC++の機能は、代替ソリューションを提供します。例えば:
struct vector3 {
float v[3];
float &operator[] (int i) { return v[i]; }
float &x() { return v[0]; }
float &y() { return v[1]; }
float &z() { return v[2]; }
};
* C11は明らかに匿名の構造体を追加するため、C++の将来の改訂で追加される可能性があります。
vector3
を使用することによる宣言union
union vector3 {
struct { float x, y, z; } ;
float v[3] ;
} ;
確かに、 匿名構造はMSVC拡張機能でした 。しかし、ISO C11は現在それを許可しており、 gccは許可しています であり、Appleのllvmコンパイラも許可しています。
なぜC11でC++ 11ではないのですか?確かではありませんが、実際にはほとんどの(gcc ++、MSVC++、AppleのC++コンパイラ)C++コンパイラがそれらをサポートしています。
よく分からない。 C++仕様のセクション9.5、条項2:
フォームの結合
union { member-specification } ;
匿名組合と呼ばれます。名前のないタイプの名前のないオブジェクトを定義します。
このようなこともできます:
void foo()
{
typedef
struct { // unnamed, is that what you mean by anonymous?
int a;
char b;
} MyStructType; // this is more of a "C" style, but valid C++ nonetheless
struct { // an anonymous struct, not even typedef'd
double x;
double y;
} point = { 1.0, 3.4 };
}
必ずしも非常に便利というわけではありません...厄介なマクロ定義では時々便利です。
組合は匿名にすることができます。標準、9.5段落2を参照してください。
匿名の構造体またはクラスは、どのような目的を果たしていると思いますか?なぜ標準にないのかを推測する前に、なぜそうあるべきなのかを知りたいのですが、匿名の構造体の使い方はわかりません。
編集、コメント、およびこのMSDN記事: 匿名構造 に基づいて、推測するのは危険です-カプセル化の概念にはあまり適合しません。クラスのメンバーが1つのメンバーを追加するだけでなく、クラスのメンバーがクラスの名前空間を台無しにすることはないでしょう。さらに、匿名構造を変更すると、許可なくクラスに影響を与える可能性があります。
あなたのコード
union {
struct {
float x;
float y;
float z;
};
float v[3];
};
のようなものです
union Foo {
int;
float v[3];
};
これは確かに無効です(C99以前)。
その理由は、(Cで)解析を単純化するためにおそらくです。その場合、構造体/ユニオン本体に「宣言子ステートメント」のみがあることを確認するだけでよいからです。 」のような
Type field;
つまり、 gccおよび "other compilers" は、名前のないフィールドを拡張機能としてサポートします。
Edit:C11では、匿名の構造体が公式にサポートされるようになりました(§6.7.2.1/ 13)。