Почему С++ 11 не поддерживает анонимные структуры, а C11?

C11 поддерживает анонимные структуры, например:

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

В принципе, члены такого struct обрабатываются так, как если бы они были членами включенных struct или union (рекурсивно, если вложенная структура сама была анонимной).

В чем была причина для С++ 11, не включая анонимные структуры? Они, безусловно, очень полезны (в основном внутри профсоюзов, чтобы исключить типизацию идентификатора для struct). Но они кажутся достаточно очевидным дополнением к спецификации (и уже реализованной многими компиляторами), что, безусловно, должно было быть обсуждено, по крайней мере, для сохранения совместимости со стандартом C11. Почему они не добавили?

Ответ 1

Небольшие усилия были предприняты для поддержания совместимости между С++ и C при развитии двух языков. Обратите внимание, что массивы стеков с переменной длиной были с C с 1999 года, но не были включены в С++ 11. Хотя они, как правило, не вводят противоречащих друг другу вещей, комитет С++ не совсем наклоняется назад, чтобы убедиться, что С++ 11 совместим с версиями C за пределами C89.

Кроме того, эта функция будет довольно сложной в С++, потому что struct является не более чем class. А анонимная структура/класс должна иметь все функции регулярной структуры/класса, да? В противном случае, какой смысл иметь его?

Что означало бы создание безымянного struct? Как бы вы определили конструктор? Что-то простое:

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

просто невозможно, потому что внутренний struct не имеет конструктора. И нет способа указать его. A struct не может создавать члены другого struct внутри него.

Что-то вроде этого:

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

Что делает this указатель SomeFunc get? Каким будет тип this, безымянный и неназванный тип? Как бы вы даже определили SomeFunc вне структуры? Имя SomeFunc не может быть Foo::SomeFunc, потому что SomeFunc живет во внутренней области.

Это слишком сложно для С++. И, конечно, не стоит достаточно, чтобы потрудиться с добавлением этой сложности для.

Ответ 2

Чтобы играть в защитника дьявола - объявления класса и структуры часто используются для обертывания объявлений типа класса.

typedef struct {

} name;

поэтому должно быть допустимым.

Поэтому

struct {

} 

также должен быть.

Однако, если мы рассматриваем это как просто объявление внутри внутреннего пространства имен класса, не будет доступа к внутренней части структуры.

Так как struct!= namespace в C, C может составлять такие правила, как доступ к анонимной структуре через окружающую структуру.

Для С++, чтобы это разрешить, в этой ситуации потребуется особый случай, что усложнит разрешение имен.

Конечно, играя дьявола-адвоката дьявола - C на самом деле это делал. Он добавил дополнительный уровень, чтобы назвать разрешение - если вы не можете найти имя в столбце, проверьте, что анонимные члены структуры. Это немного волшебное, так что я вижу, что члены комитета С++ находят раздражающим.

Он также вызывает вопросы - если анонимную структуру можно получить через свой родительский класс, что же касается анонимных структур в пространстве имен.

Конечно, если вы действительно хотите знать, просто спросите Stroustrup - он отвечает на письма.

Ответ 3

Он думает, что это работает в С++ 11

struct A
{
    int someVariable;
};

struct B : public A
{
    int someOtherVariable;
};

Используйте его как:

B structB;
structB.someVariable = 5;
structB.someOtherVariable = 6;

Это помогло мне решить аналогичную проблему.