Класс без названия

Я прочитал это о классе в стандартном документе С++:

Класс - это тип. Его имя становится именем класса (9.1) в пределах его области действия.

class-name: identifier template-id

Я нашел эту грамматику для идентификатора в стандарте С++:

 2.10 Identifiers
 identifier: nondigit
 identifier nondigit
 identifier digit

 nondigit: one of universal-character-name 
 _ a b c d e f g h i j k l m n o p q r s t u  v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 
 digit: one of 0 1 2 3 4 5 6 7 8 9

Теперь я попытался сделать это:

class
{
public:
  int i;
};

и он отлично компилируется без имени.

Может ли кто-нибудь дать мне объяснение по этому поводу? Разве это не нарушение грамматики, указанной для идентификатора?


Наваз задал дополнительный вопрос о соответствии кода, который я дал, стандарту. Желающие могут проверить это здесь.


person Amit Tomar    schedule 30.10.2012    source источник
comment
Я хотел бы знать, какой компилятор вы использовали: я не могу скомпилировать этот код на GCC.   -  person Alberto Moriconi    schedule 30.10.2012
comment
@AlbertoMoriconi Я использовал QtCreator(en.wikipedia.org/wiki/Qt_Creator) для того же , так что я думаю, что также следует использовать GCC. Можете ли вы опубликовать ошибку, которую вы получили?   -  person Amit Tomar    schedule 31.10.2012
comment
я получаю error: abstract declarator ‘<anonymous class>’ used as declaration   -  person Alberto Moriconi    schedule 31.10.2012
comment
@AlbertoMoriconi Пожалуйста, пройдите редактирование, я добавил ссылку на дополнительный вопрос. Ваше сомнение также обсуждается там в одном из ответов.   -  person Amit Tomar    schedule 31.10.2012


Ответы (4)


Грамматика идет

class-specifier:
    class-head { member-specification_opt }

class-head:
    class-key attribute-specifier-seq_opt class-head-name class-virt-specifier-seq_opt base-clause_opt
    class-key attribute-specifier-seq_opt base-clause_opt

class-key:
    class
    struct
    union

В вашем случае используется второе производство class-head - class-name не задействовано.

person avakar    schedule 30.10.2012

Идентификатор полностью опущен, поэтому вопрос о правильной грамматике для идентификатора является спорным. Ничто в описании не говорит, что идентификатор должен присутствовать. Анонимные классы, вероятно, разрешены для согласованности с правилами структуры C, что позволяет использовать такие конструкции, как:

typedef struct { int i; } Foo;

struct { int x, y; } points[] = { {1, 2}, {3, 4} };

Я не думаю, что когда-либо видел, как это делается для класса.

person Marcelo Cantos    schedule 30.10.2012
comment
-1, описание, которое он цитирует, говорит, что должен присутствовать идентификатор. - person Johannes Schaub - litb; 30.10.2012
comment
@JohannesSchaub-litb: эта цитата не имеет отношения к опубликованному коду. - person Nawaz; 30.10.2012
comment
вы говорите описание. Я должен предположить, что вы имеете в виду вопрос. - person Johannes Schaub - litb; 30.10.2012
comment
@JohannesSchaub-litb: Да, я имел в виду цитаты в вопросе. Я не могу найти ничего (в кавычках или иным образом) в любой версии вопроса, в которой говорится, что что-либо, напоминающее класс, должно иметь имя. Что мне не хватает? Думаю, я хлопну себя по лбу, когда ты укажешь на это, но я просто не вижу этого. - person Marcelo Cantos; 31.10.2012

class {public: int i;}

совершенно бесполезен, но вы можете указать класс без имени, а затем создать экземпляры этого класса. Зная, что вы можете использовать следующее:

class {public: int i;} a,b,c;
a.i = 5;
b.i = 4;
c.i = 3;
cout<<a.i<<" "<<b.i<<" "<<c.i;

Вы также можете использовать это внутри функции (как анонимный класс), поэтому зная, что вы можете использовать что-то вроде этого:

void x()
{
    class {public: int i;} a,b,c;
    a.i = 5;
    b.i = 4;
    c.i = 3;
    cout<<a.i<<" "<<b.i<<" "<<c.i;
}

int main() {
    x();
}
person Дамян Станчев    schedule 08.07.2014

Код class { int i; }; полностью соответствует стандарту. Вы процитировали нерелевантную ссылку из Стандарта, которая не имеет ничего общего с анонимным классом.

person Nawaz    schedule 30.10.2012
comment
@JohannesSchaub-litb: class { public: int i; }; не полностью соответствует стандарту? Зачем? - person Nawaz; 30.10.2012
comment
@JohannesSchaub-litb: Не могли бы вы сказать мне, что не так с class { public: int i; };? Почему не соответствует стандарту? (Я жду вашего ответа, так что я могу знать это сам). - person Nawaz; 30.10.2012
comment
в то время как это грамматически допустимо, это нарушает правило, согласно которому такой класс должен объявить по крайней мере одно имя в своей охватывающей области. - person Johannes Schaub - litb; 30.10.2012
comment
@JohannesSchaub-litb: я не понял. О каком имени ты говоришь? Не могли бы вы уточнить это? - person Nawaz; 30.10.2012
comment
вы можете задать вопрос Stackoverflow, если вас интересуют подробные объяснения. Эти поля комментариев слишком малы для этого. - person Johannes Schaub - litb; 30.10.2012
comment
@JohannesSchaub-litb: Готово. stackoverflow .com/questions/13138605/ - person Nawaz; 30.10.2012