Когда все разве оператор запятой не действует как оператор запятой?

Если Вы видите этот код,

class A{
public:
    A(int a):var(a){}
    int var;
};

int f(A obj) {
    return obj.var;
}

int main() {
    //std::cout<<f(23);    // output: 23
    std::cout<<f(23, 23);  // error: too many arguments to function 'int f(A)'
    return 0;
}

f(23, 23) не компилирует, потому что запятая действует как разделитель здесь и не как оператор запятой.

Где все разве запятая не работает оператором запятой? Или наоборот?

8
задан Lazer 28 June 2010 в 09:32
поделиться

5 ответов

С грамматической точки зрения параметры вызова функции образуют необязательное выражение-список внутри круглых скобок. Список expression-list состоит из одного или нескольких assignment-expression, разделенных маркером запятой. Запятая может означать оператор запятой только там, где ожидается выражение.

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

Например, вы можете окружить любое выражение (включая выражение с использованием оператора запятой) скобками, чтобы получить primary-expression, которое является assignment-expression и, следовательно, допустимо в expression-list.

Например,

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

f( a, b );

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

f( (a, b) );
11
ответ дан 5 December 2019 в 05:02
поделиться

Я просмотрел черновой вариант Стандарта. По сути, в грамматике продукция -списка - это те, в которых есть запятые для разделения различных элементов. Следующие результаты относятся к C ++ 03. В C ++ 0x список-выражений напрямую делегирует список-инициализаторов , потому что в C ++ 0x списки фигурных скобок могут также встречаться в аргументах функций и конструкторов.

  • список-выражений Для аргументов функции / конструктора (включая функциональные преобразования)
  • список-перечислитель Список элементов перечисления
  • инициализатор-декларатор -list Различные имена, объявленные в одном объявлении

    Пример:

     int a, b;
    
  • список-объявлений-параметров список-объявлений-параметров (сюрприз!) функции
  • список-инициализаторов Список похож на список-выражений, но может включать списки выражений в фигурных скобках. Используется для агрегатной инициализации (инициализации массивов или структур)
  • список-деклараторов-членов Аналогично списку деклараторов инициализации, но для объявлений членов в классах.

    Пример:

     struct A {int a, b; };
    
  • список-спецификаторов баз Список базовых классов класса.
  • mem-initializer-list Список инициализаторов для членов

    Пример:

     struct A {A (): a (0), b (0) {} int a; int b; };
    
  • список-параметров-шаблона Список объявлений параметров шаблона .
  • список-аргументов-шаблона Список аргументов шаблона , переданных в шаблон.
  • type-id-list Список типов для спецификаций исключений

    Пример:

     void f () throw (int, bool) {}
    

Существует список идентификаторов для параметров макроса, которого у меня нет в этом списке, потому что это действительно часть грамматики препроцессора.

8
ответ дан 5 December 2019 в 05:02
поделиться

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

f(1, 2) - это выражение вызова функции с двумя параметрами. И наоборот, f((1, 2)) - это выражение вызова функции с одним параметром, которым является подвыражение 1, 2, которое оценивается в 2.

7
ответ дан 5 December 2019 в 05:02
поделиться

Использование запятой в качестве символа оператор отличается от его использования в вызовы функций и определения, объявления переменных, перечисление объявления и подобные конструкции, где он действует как разделитель.

Википедия - Оператор запятой

8
ответ дан 5 December 2019 в 05:02
поделиться

Оператор запятой всегда действует как оператор запятой, но запятая не всегда означает оператор запятой - иногда это просто знак препинания.

Что касается знаков препинания, то простой ответ - «когда так сказано в стандарте». Прохождение всех ситуаций, в которых так сказано в стандарте, дает гораздо более длинный ответ, но тот, который вряд ли будет намного более полезным, потому что (например) он должен иметь дело с рядом угловых случаев, которым большинство людей не заботится о.

1
ответ дан 5 December 2019 в 05:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: