関数
関数は文の並び (関数の本体) を名前およびゼロ個以上の関数の仮引数のリストと紐付ける C++ のエンティティです。
// 関数名「isodd」// 仮引数リストには名前が「n」で型が int の1個の仮引数があります// 戻り値の型は boolbool isodd(int n){// 関数の本体の始まりreturn n %2;}// 関数の本体の終わり
関数が呼び出されたとき (例えば関数呼び出し式で)、仮引数は実引数 (呼び出しの場所で提供されるか、デフォルト化されるか、いずれか) から初期化され、関数の本体の文が実行されます。
int main(){for(int arg :{-3, -2, -1, 0, 1, 2, 3})std::cout<< isodd(arg)<<' ';// isodd が7回呼ばれ、その度に// n が arg からコピー初期化されます。}
関数は、戻ることによって、または例外を投げることによって、終了できます。
関数はコルーチンであることもあります。 この場合、後に再開するために実行を中断することができます。 | (C++20以上) |
関数の宣言は任意のスコープ内に現れることができますが、関数の定義は、名前空間スコープ内、または、クラススコープ内 (メンバ関数およびフレンド関数の場合) にのみ、現れることができます。 クラスの本体の中で friend 指定子なしに宣言された関数は、クラスのメンバ関数です。 そのような関数は追加の性質を多く持ちます。 詳細はメンバ関数を参照してください。
関数はオブジェクトではありません。 関数の配列というものはなく、関数を値渡ししたり他の関数から返したりすることはできません。 関数へのポインタや参照は認められており、関数そのものではできないところで使用することができます。
それぞれの関数は型を持ちます。 これは関数の戻り値の型、すべての仮引数の型 (配列からポインタ、関数からポインタへの変換後 (仮引数リストを参照))、関数が noexcept かどうか(C++17以上)、 cv 修飾子および参照修飾子 (メンバ関数の場合) から構成されます。 関数の型には言語リンケージも含まれます。 cv 修飾された関数型というものはありません (int f()const; のような cv 修飾された関数の型や std::stringconst f(); のような cv 修飾された型を返す関数と混同しないでください)。
ラムダ式によって名前のない関数を生成できます。
仮引数リストおよび cv/参照修飾 (メンバ関数の場合) が異なる限り、同じスコープ内の複数の関数が同じ名前を持つことができます。 これは関数のオーバーロードと呼ばれます。 戻り値の型および noexcept 指定(C++17以上)のみが異なる関数の宣言はオーバーロードできません。
This section is incomplete Reason: links to other Function subpages |
[編集]関数オブジェクト
関数の左辺値だけでなく、関数呼び出し式は関数へのポインタ、逆参照されたメンバ関数へのポインタ、ラムダ式、および関数呼び出し演算子をオーバーロードするあらゆるクラス型の変数をサポートします。 これらの型はまとめて関数オブジェクトと呼ばれ、 C++ の標準ライブラリの様々なところで使用されます。 例えば、 BinaryPredicate や Compare の用途を参照してください。
標準ライブラリは多くの定義済みの関数オブジェクトのテンプレートや、新しい関数オブジェクトを合成する方法 (std::mem_fn, std::bind, std::function など) も提供しています。