web-dev-qa-db-ja.com

C11が匿名構造体をサポートしているのに、C ++ 11が匿名構造体をサポートしていないのはなぜですか?

C11は、次のような匿名構造をサポートしています。

struct Foo
{
    struct
    {
        size_t x, y;
    };
};
struct Foo f;
f.x = 17;
f.y = 42;

基本的に、このようなstructのメンバーは、囲んでいるstructまたはunionのメンバーであるかのように扱われます(再帰的に、囲んでいる構造自体が匿名の場合)。

匿名構造も含まないC++ 11の理由は何でしたか?確かに、これらはまれにしか役に立ちません(ほとんどの場合、ユニオン内で、structの識別子の入力を排除します)。しかし、それらは仕様(および多くのコンパイラーによってすでに実装されているもの)への十分に明白な追加であるように思われるので、少なくともC11標準との互換性を維持するためにそれらは確かに議論されたに違いありません。では、なぜ追加されなかったのでしょうか。

43
Jeff Walden

2つの言語が進化するにつれて、C++とCの間の互換性を維持するための努力はほとんど行われていません。可変長スタック配列は1999年からCに含まれていますが、C++ 11には含まれていません。それらは一般に互いに矛盾するものを紹介しませんが、C++委員会はC++ 11がC89以降のバージョンのCと互換性があることを確認するために正確に後ろ向きに曲がっていません。

さらに、structclassにすぎないため、この機能はC++では非常に複雑になります。そして、匿名の構造体/クラスは、通常の構造体/クラスのすべての機能を備えている必要がありますね。そうでなければ、それを持っていることのポイントは何ですか?

名前のないstructを作成するとはどういう意味ですか?コンストラクターをどのように定義しますか?次のような単純なもの:

struct Foo
{
    struct
    {
        size_t &x;
    };
};

内部のstructにはコンストラクターがないため、単純に不可能です。そして、1つを指定する方法はありません。 structは、その中に別のstructのメンバーを作成できません。

このようなものの場合:

struct Foo
{
    size_t outer;
    struct
    {
        void SomeFunc();
        size_t x;
    };
};

thisはどのSomeFuncポインタを取得しますか? thisのタイプは、名前のないタイプと名前のないタイプでしょうか。構造体の外でSomeFuncをどのように定義しますか? SomeFuncは内部スコープに存在するため、SomeFuncの名前をFoo::SomeFuncにすることはできません。

C++では処理するには複雑すぎます。そして確かに、その複雑さを追加することを気にするほど価値はありません。

44
Nicol Bolas

悪魔の代弁者を演じるために-クラスと構造体の宣言は、クラス固有の型宣言をラップするためによく使用されます。

typedef struct {

} name;

したがって、許容できるはずです。

したがって、

struct {

} 

同様にする必要があります。

ただし、これをクラスの内部名前空間内の単なる宣言と見なすと、構造体の内部にアクセスする方法がありません。

Cのstruct!=名前空間であるため、Cは、周囲の構造体を介して匿名の構造体にアクセスするようなルールを作成できます。

C++でこれを可能にするには、この状況を特別な場合にする必要があり、名前解決が複雑になります。

もちろん、悪魔の代弁者を演じること-Cは実際にこれをしました。名前解決に追加のレベルが追加されました。構造体で名前が見つからない場合は、構造体の匿名メンバーを確認してください。これは少し不思議なことです。C++委員会のメンバーが迷惑を感じているのを見ることができます。

また、親クラスを介して匿名構造体にアクセスできる場合、名前空間内の匿名構造体についてはどうでしょうか。

もちろん、本当に知りたい場合は、Stroustrupに聞いてください。彼はメールに返信します。

4