Почему С++ 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;
Это помогло мне решить аналогичную проблему.