namespace: 名前衝突を防ぐ

コードを論理的にグループ化。大規模プロジェクトの必須機能。

namespace
名前の衝突を防ぐスコープ。
using
名前空間のメンバを取り込む。
無名名前空間
ファイル内限定のスコープ。

名前空間

同姓同名の回避 (Surname)

名前空間は「名字(姓)」です。クラスに「佐藤さん」と「鈴木さん」がいれば、単に「ひろし君」と呼んでも区別できません。「佐藤::ひろし」と呼べば確実です。プログラムも大きくなれば、同じ名前の関数(衝突)が増えるため、名字をつけて区別します。

C++標準ライブラリはすべて `std`(Standard)という名前空間に入っています。`using namespace std;` と書くのは、「このクラスでは全員、名字なしで呼ぶ!」と宣言するようなもので、衝突のリスクが高まるため、大きなプログラムでは嫌われます。

namespace Basics
namespace myapp {
void greet() {
std::cout << "Hello from myapp!
";
}
// ネストされた名前空間
namespace utils {
int add(int a, int b) { return a + b; }
}
}
// 使用
myapp::greet();
myapp::utils::add(1, 2);
// using 宣言(個別にインポート)
using myapp::greet;
greet(); // myapp:: 不要
実行結果
myapp::greet() → Hello from myapp!\nmyapp::utils::add(1,2) → 3
Bad
// ❌ Bad: using namespace std;
// これをやると std:: 内の全関数が見えるようになる
using namespace std; // 全て見える — 名前衝突の危険
// もし自分も sort 関数を作っていたら?
// コンパイラはどちらを使うか迷ってエラーになる(曖昧さ)
sort(v.begin(), v.end());
Good
// ✅ Good: 必要なものだけ
using std::cout;
using std::endl;
// または std:: を毎回書く
std::sort(v.begin(), v.end());

パターン

inline, anonymous, nested
// インライン名前空間 (バージョン管理)
namespace mylib {
inline namespace v2 { // デフォルトで v2 が使われる
void foo() { std::cout << "v2
"; }
}
namespace v1 {
void foo() { std::cout << "v1
"; }
}
}
mylib::foo(); // v2::foo
mylib::v1::foo(); // v1::foo
// 無名名前空間(ファイル内限定)
// static int internal_var = 42; と同じ効果だが、より現代的
namespace {
int internal_var = 42; // このファイルのみ
}
// ネストを短く書く (C++17)
namespace A::B::C {
void func() { }
}
Tip: using namespace は .cpp ファイル内でのみ。ヘッダ(.h)では禁止(インクルード先全てに影響するため)。

合格ライン

名前空間を定義・使用できる
using namespace std; をヘッダに書いてはいけない理由を説明できる

参考リンク

演習課題

課題1: 名前空間の定義
自分のライブラリ用の名前空間を作成してください。
課題2: ネスト名前空間
C++17 のネスト名前空間構文を使ってください。

次のステップ