Почему я должен заключить в скобки инициализирующее выражение, которое является выражением запятой?

Разбирая проблему, я имею в виду ее сущность, я могу инициализировать переменную как int, выполнив вначале лямбду бездействия в выражении через запятую, например так:

int main(){
auto x = ( []{}(), 10 );          // same effect as auto x = 10;
}

Но если я не заключу в скобки инициализирующее выражение,

int main(){
auto y = []{}(), 10;              // won't compile
}

все gcc, clang и MSVC жалуются на попытки инициализации y с void выражение.

Почему я должен заключить в скобки выражение запятой, чтобы использовать его в качестве инициализатора?

3

Решение

В декларации , Символ отделяет деклараторов. Более простой пример:

int i = 2, j = 3;     // OK: declares `i` and `j`
int i = 2, 3;         // Error: `3` is not a declarator

Во втором случае это выглядит неоднозначно. Это , разделители, или это , часть выражения 2, 3?

Чтобы устранить эту неоднозначность, мы можем обратиться к грамматике языка (C ++ 14 [dcl.decl]):

простая декларация:

    Децл-спецификатор-слвыбирать INIT-описатель-листвыбирать ;

    атрибут-спецификатор-seq decl-спецификатор-seqвыбирать INIT-описатель-лист ;

INIT-описатель-лист:

    INIT-описатель

    INIT-описатель-лист , INIT-описатель

INIT-описатель:

    инициализатор объявлениявыбирать

То, как работают грамматики, это означает, что при разборе объявления самая длинная последовательность, которая соответствует INIT-описатель , Считается. (Это иногда называют «принципом максимального жаворонка»). Так int i = 2, Матчи INIT-описатель , . затем 3 не соответствует init-declarator, так что разбора не получается.

5

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector