Когда все оператор запятой не действует как оператор запятой? - PullRequest
8 голосов
/ 27 июня 2010

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

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) не компилируется, потому что запятая действует здесь как разделитель, а не как запятая. не работать как оператор запятой?Или наоборот?

Ответы [ 5 ]

11 голосов
/ 27 июня 2010

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

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

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

Например,

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

f( a, b );

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

f( (a, b) );
8 голосов
/ 28 июня 2010

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

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

    Пример: * * тысяча двадцать-восемь

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

    Пример: * * тысяча пятьдесят-три

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

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

    Пример:

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

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

8 голосов
/ 27 июня 2010

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

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

7 голосов
/ 27 июня 2010

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

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

1 голос
/ 27 июня 2010

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

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

...