関数呼び出し演算子: ()

関数呼び出しは、関数または呼び出し可能オブジェクトに評価される式で形成されたある種類の postfix-expression 式の後に、関数呼び出し演算子 () を付けたものです。 オブジェクトは、そのオブジェクトの関数呼び出しセマンティクスを提供する、operator () 関数を呼び出すことができます。

構文

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

解説

関数呼び出し演算子への引数は、式のコンマ区切りの一覧である argument-expression-list から得られます。 これらの式の値が、引数として関数に渡されます。 argument-expression-list は空の場合もあります。 C++17 より前では、関数式と引数式の評価の順序は指定されておらず、どのような順序でも発生する可能性があります。 C++17 以降では、関数式は、いずれの引数式および既定の引数よりも前に評価されます。 引数式は、不定の順序で評価されます。

postfix-expression は、呼び出す関数に評価されます。 次のいずれかの形式となります。

  • 現在のスコープ内、または指定されたいずれかの関数で可視の、関数識別子
  • 関数、関数ポインター、呼び出し可能オブジェクト、またはいずれかの参照に評価される式
  • メンバー関数アクセサー (明示的または暗黙的)
  • メンバー関数への逆参照されたポインター。

postfix-expression は、オーバーロードされた関数識別子か、オーバーロードされたメンバー関数アクセサーであることがあります。 オーバーロードの解決の規則によって、呼び出す実際の関数が決定されます。 メンバー関数が virtual の場合、呼び出す関数は実行時に決定されます。

宣言の例を次に示します。

  • 関数の戻り値の型 T。 以下に宣言例を示します。

    T func( int i );
    
  • 関数の戻り値の型へのポインター T。 以下に宣言例を示します。

    T (*func)( int i );
    
  • 関数の戻り値の型への参照 T。 以下に宣言例を示します。

    T (&func)(int i);
    
  • メンバー関数の逆参照戻り値の型へのポインター T。 以下に、関数呼び出しの例を示します。

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

次の例では、3 個の引数を持つ標準ライブラリ関数 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 に評価されます。 参照戻り値の型を持つ関数は、lvalue に評価されます。 これらの関数は、次に示すように、代入ステートメントの左辺で使用できます。

// 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";
}

上記のコードでは、x および y 座標を表すプライベート データ オブジェクトが入っている、Point というクラスが定義されています。 これらのデータ オブジェクトを変更し、値を取得する必要があります。 このプログラムは、このようなクラスのいくつかの設計の 1 つに過ぎません。GetXSetX または GetYSetY 関数を使う設計も可能です。

クラス型を返す関数、クラス型へのポインター、またはクラス型への参照は、メンバー選択演算子の左のオペランドとして使用できます。 次のコードは有効です。

// 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 );
}

関数は再帰的に呼び出すことができます。 関数の宣言の詳細については、「関数」を参照してください。 関連する資料が「翻訳単位とリンケージ」にあります。

関連項目

後置式
C++ の組み込み演算子、優先順位、結合規則
関数呼び出し