Оператор вызова функции: ()

Вызов функции — это типpostfix-expression, сформированный выражением, которое вычисляет функцию или вызываемый объект, за которым следует оператор вызова функции. () Объект может объявить функцию operator () , которая предоставляет семантику вызова функции для объекта.

Синтаксис

postfix-expression:
postfix-expression ( argument-expression-list opt )

Замечания

Аргументы оператора вызова функции приходят из argument-expression-listсписка выражений, разделенных запятыми. Значения этих выражений передаются функции в качестве аргументов. Список аргументов-выражений может быть пустым. До C++17 порядок вычисления выражения функции и выражений аргументов не определен и может произойти в любом порядке. В C++17 и более поздних версиях выражение функции вычисляется до любых выражений аргументов или аргументов по умолчанию. Выражения аргументов вычисляются в неопределенной последовательности.

Функция postfix-expression вычисляет вызываемую функцию. Он может принимать любую из нескольких форм:

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

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

Некоторые примеры объявлений:

  • Функция, возвращающая тип T. Пример объявления:

    T func( int i );
    
  • Указатель на функцию, возвращающую тип T. Пример объявления:

    T (*func)( int i );
    
  • Ссылка на функцию, возвращающую тип T. Пример объявления:

    T (&func)(int i);
    
  • Разыменование функции указателя на член, возвращающее тип T. Примеры вызовов функции:

    (pObject->*pmf)();
    (Object.*pmf)();
    

Пример

В следующем примере вызывается функция стандартной библиотеки strcat_s с тремя аргументами:

// expre_Function_Call_Operator.cpp
// compile with: /EHsc

#include <iostream>
#include <string>

// C++ Standard Library name space
using namespace std;

int main()
{
    enum
    {
        sizeOfBuffer = 20
    };

    char s1[ sizeOfBuffer ] = "Welcome to ";
    char s2[ ] = "C++";

    strcat_s( s1, sizeOfBuffer, s2 );

    cout << s1 << endl;
}
Welcome to C++

Результаты вызова функции

Вызов функции вычисляется на значение rvalue, если функция не объявлена как ссылочный тип. Функции с ссылочными возвращаемыми типами оцениваются на lvalues. Эти функции можно использовать в левой части инструкции назначения, как показано ниже:

// expre_Function_Call_Results.cpp
// compile with: /EHsc
#include <iostream>
class Point
{
public:
    // Define "accessor" functions as
    // reference types.
    unsigned& x() { return _x; }
    unsigned& y() { return _y; }
private:
    unsigned _x;
    unsigned _y;
};

using namespace std;
int main()
{
    Point ThePoint;

    ThePoint.x() = 7;           // Use x() as an l-value.
    unsigned y = ThePoint.y();  // Use y() as an r-value.

    // Use x() and y() as r-values.
    cout << "x = " << ThePoint.x() << "\n"
         << "y = " << ThePoint.y() << "\n";
}

Приведенный выше код определяет класс, который Pointсодержит объекты частных данных, представляющие координаты x и y . Эти объекты данных необходимо изменить, а значения — извлечь. Программа — это лишь одно из нескольких решений для такого класса. Также можно использовать функции GetX и SetX или GetY и SetY.

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

// expre_Function_Results2.cpp
class A {
public:
   A() {}
   A(int i) {}
   int SetA( int i ) {
      return (I = i);
   }

   int GetA() {
      return I;
   }

private:
   int I;
};

A func1() {
   A a = 0;
   return a;
}

A* func2() {
   A *a = new A();
   return a;
}

A& func3() {
   A *a = new A();
   A &b = *a;
   return b;
}

int main() {
   int iResult = func1().GetA();
   func2()->SetA( 3 );
   func3().SetA( 7 );
}

Функции можно вызывать рекурсивно. Дополнительные сведения о объявлениях функций см. в разделе "Функции". Связанные материалы относятся к единицам перевода и компоновке.

См. также

Выражения postfix
Встроенные операторы C++, приоритет и ассоциативность
Вызов функции