C++ の関数は C の延長上にありますが、3 つの強力な拡張があります:オーバーロード(同じ名前で違う引数の関数)、デフォルト引数(省略できる引数)、const 参照渡し(重い型を速く・安全に渡す)。これで C の時代に書いていた print_int() / print_double() / print_string() の命名分けや、長すぎる引数リストから解放されます。
このページで押さえること
✅ 最低限ここだけ覚える
同じ名前で引数の型や個数が違う関数が書ける(オーバーロード)
引数に =既定値 を書けば省略可能(デフォルト引数)
重い型を渡すときは const T&
書き換えたい引数は T&
⭐ 余裕があれば読む
オーバーロード解決のルール
デフォルト引数を持てるのは「末尾の引数から」
trailing return type auto f() -> int
ヘッダで宣言/cpp で定義の書き分け
1. まず触ってみる ― 同じ名前で使い分け
C の関数との最大の違いは「同じ名前で違う関数を定義できる」こと。これをオーバーロードと呼びます。型に応じて呼び分ける仕組みで、STL の std::sort や std::max がこれで実装されています。
▶ どの関数が呼ばれる?
下の「候補となる関数」から、引数に応じてどれが選ばれるかを確認
voidprint(int n);
voidprint(double x);
voidprint(conststd::string& s);
voidprint(int n, int m);
まずは 3 つだけ
今日覚える最小の書き方:
first_func.cppC++ 最小例
// ① オーバーロード:同じ名前で違う引数intmax(int a, int b) { return a > b ? a : b; }
doublemax(double a, double b) { return a > b ? a : b; }
// ② デフォルト引数:省略可能voidgreet(std::string name = "World") {
std::cout << "Hello, " << name << "\n";
}
// ③ const 参照渡し:コピーせず、書き換えもさせないvoidshow(conststd::string& s) {
std::cout << s;
}
Q. C で使っていた関数(strlen など)は C++ から呼べる?
→ 呼べます。#include <cstring>(C の string.h 相当)で使えます。
2. 関数の基本(C との差分)
関数の基本構文は C と同じですが、微妙な違いがいくつかあります。
CC
// 引数なしは void を明示inthello(void);
// プロトタイプ宣言が必要intadd(int, int);
intmain(void) {
returnadd(1, 2);
}
intadd(int a, int b) {
return a + b;
}
C++C++
// 引数なしは () でよい(void 省略)inthello();
// main 末尾の return 0; も省略可(非推奨)intmain() {
returnadd(1, 2); // 前方宣言がなくてもエラーになる点は同じ
}
intadd(int a, int b) {
return a + b;
}
引数なしと void
C では int f() と書くと「引数の情報なし(任意個の引数を受け取れる、という意味)」でした。だから int f(void) と明示していました。C++ では int f() は「引数なし」を明示する書き方です。void は書いても書かなくても OK で、現代の C++ では省略するのが一般的。
プロトタイプ宣言は C と同じ
関数を呼び出す位置より後に定義を書く場合は、前もって宣言(プロトタイプ)が必要です。C と同じ。ヘッダファイルに宣言、.cpp に定義、という分離は C++ でも基本です(詳しくは「複数ファイル分割」の回で)。
トレイリング戻り型 -> 型(C++11)
C++11 から、戻り値の型を関数名の後ろに書く記法が使えます:
後置戻り型C++11~
// 従来intadd(int a, int b) { return a + b; }
// 後置(意味は同じ)autoadd(int a, int b) -> int { return a + b; }
voidf(int a, int b = 0, int c = 0);
f(1); // a=1, b=0, c=0f(1, 2); // a=1, b=2, c=0f(1, 2, 3); // a=1, b=2, c=3
NGエラー
voidf(int a = 0, int b, int c);
// ← NG: 途中だけデフォルトvoidg(int a, int b = 0, int c);
// ← NG: デフォルトの後ろに非デフォルト
オーバーロードとの競合に注意: デフォルト引数を持つ関数と、同名のオーバーロードを両方作ると「どちらを呼ぶのか曖昧」になりエラー。たとえば void f(int a, int b = 0); と void f(int a); が両方あると、f(1); でどちらを呼ぶか決められません。どちらか片方にするのが無難。