Почему C ++ 11 не поддерживает анонимные структуры, а C11 -? - PullRequest
43 голосов
/ 24 декабря 2011

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 ]

43 голосов
/ 24 декабря 2011

Мало усилий было сделано для обеспечения совместимости между 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 ++ иметь дело с.И, конечно, не стоит того, чтобы ломать голову над этой сложностью.

3 голосов
/ 12 ноября 2013

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

typedef struct {

} name;

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

Следовательно

struct {

} 

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

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

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

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

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

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

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

...