Почему C++11 не поддерживает анонимные структуры, а C11 -?
C11 поддерживает анонимные структуры, например:
struct Foo
{
struct
{
size_t x, y;
};
};
struct Foo f;
f.x = 17;
f.y = 42;
В основном, члены такого struct
обрабатываются так, как если бы они были членами struct
или же union
(рекурсивно, если ограждающая структура сама была анонимной).
Каково было обоснование того, что C++11 также не включает анонимные структуры? Они только необычайно полезны (в основном внутри союзов, чтобы исключить ввод идентификатора для struct
), конечно. Но они кажутся достаточно очевидным дополнением к спецификации (и уже реализованным многими компиляторами), что, безусловно, их нужно было обсудить, по крайней мере, для сохранения совместимости со стандартом C11. Так почему они не были добавлены?
2 ответа
Небольшое усилие было сделано для поддержания совместимости между C++ и C по мере развития двух языков. Обратите внимание, что стековые массивы переменной длины были в C с 1999 года, но не были включены в C++11. Хотя они, как правило, не представляют вещи, которые противоречат друг другу, комитет по С ++ не склоняется к тому, чтобы быть уверенным, что С ++ 11 совместим с версиями С, выходящими за пределы С89.
Кроме того, эта функция будет довольно сложной в C++, потому что struct
не более чем class
, И у анонимной структуры / класса должны быть все функции регулярной структуры / класса, да? Иначе, какой смысл иметь это?
Что бы это значило построить безымянный struct
? Как бы вы определили конструктор? Что-то простое, как:
struct Foo
{
struct
{
size_t &x;
};
};
просто невозможно, потому что внутренний struct
не имеет конструктора И нет способа указать один. struct
не может построить членов другого struct
внутри.
Для чего-то вроде этого:
struct Foo
{
size_t outer;
struct
{
void SomeFunc();
size_t x;
};
};
Какие this
указатель делает SomeFunc
получить? Какой бы тип this
быть, безымянный и безымянный тип? Как бы вы даже определили SomeFunc
вне структуры? Имя SomeFunc
не может быть Foo::SomeFunc
, так как SomeFunc
живет во внутренней сфере.
Это просто слишком сложно для C++ иметь дело с. И, конечно, не стоит того, чтобы ломать голову над сложностью.
Чтобы играть адвокат дьявола - объявления классов и структур часто используются, чтобы обернуть объявления типов для классов.
typedef struct {
} name;
поэтому должно быть допустимым.
Следовательно
struct {
}
должно быть так же.
Однако, если мы рассмотрим это как просто объявление во внутреннем пространстве имен класса, не будет никакого доступа к внутренней части структуры.
Поскольку пространство имен struct!= В C, C может создавать правила, такие как доступ к анонимной структуре через окружающую структуру.
Для того, чтобы C++ мог это разрешить, ему потребуется особый случай в этой ситуации, что усложнит разрешение имен.
Конечно, играя адвокат дьявола дьявола - С на самом деле сделал это. Добавлен дополнительный уровень разрешения имен - если вы не можете найти имя в структуре, проверьте анонимных членов структуры. Что немного волшебно, так что я могу видеть, что члены комитета C++ находят раздражающими.
Это также вызывает вопросы - если анонимная структура может быть доступна через ее родительский класс, как насчет анонимных структур в пространстве имен.
Конечно, если вы действительно хотите знать, просто спросите Страуструпа - он отвечает на электронные письма.