本文へスキップ
BecomeCoder

C++コース · 第17章 例外処理とモダンな機能 · レッスン69

enum class と namespace ― 名前を整理する

ブラウザで完結

導入

大きなプログラムでは「名前の衝突」や「意味のない数値」が問題になります。それを防ぐのが、型安全な列挙 enum class と、名前をまとめる namespace です。読みやすく安全なコードの下ごしらえです。

説明

enum class は、名前付きの定数の集まりを「独立した型」として定義します。古い enum と違い、勝手に int に変換されず、名前の衝突も起きません。

#include <iostream>
using namespace std;

enum class Color { Red, Green, Blue };   // 型安全な列挙

void paint(Color c) {
    if (c == Color::Red) cout << "赤で塗る" << endl;
    else if (c == Color::Green) cout << "緑で塗る" << endl;
    else cout << "青で塗る" << endl;
}

int main() {
    Color c = Color::Green;    // 必ず Color:: を付ける
    paint(c);                  // 緑で塗る
    // int n = c;              // ← エラー(勝手に int にならない=安全)
    return 0;
}

namespace は、関連する関数・型を名前でまとめ、他所との衝突を防ぎます。名前空間::名前 でアクセスします。std:: もその一例です。

flowchart TB
  subgraph geo["namespace geometry"]
    a["double area(...)"]
  end
  subgraph phys["namespace physics"]
    b["double area(...)"]
  end
  note["同じ area でも<br/>geometry::area と physics::area で区別できる"]
#include <iostream>
using namespace std;

namespace geometry {
    double circleArea(double r) { return 3.14159 * r * r; }
}

int main() {
    cout << geometry::circleArea(2.0) << endl;   // 12.5664
    return 0;
}

まとめ

enum class は型安全な列挙で、Color::Red のように使い、暗黙の int 変換を防ぎます。namespace は名前をまとめて衝突を避ける仕組み(std:: もこれ)。どちらも「意味のある名前で安全に区別する」ための、規模が大きくなるほど効く道具です。

実際に動かしてみよう

下のエディタにC++を書いて「コンパイル & 実行」を押すと、ブラウザ内で本物のC++コンパイラ(clang + libc++)がその場でコンパイルして実行し、出力が表示されます。std::string・vector・クラス・テンプレート・STL などモダンC++がそのまま動きます。本文の例を書き換えて試しながら進めましょう(初回だけコンパイラの読み込みに時間がかかります。以降はキャッシュされます。この回は標準入力(cin)は使わず、値はコードに直接書きます)。

C/C++ — ブラウザ内で本物のコンパイラで実行

ブラウザ内で本物のC/C++コンパイラ(clang + libc++ / WebAssembly)を動かします。構造体・malloc/free・std::string・vector・クラス・テンプレート・STL などがそのまま実行できます(初回のみコンパイラの読み込みに時間がかかります。以降はブラウザにキャッシュされます)。
スクロールして表示された時点でも自動で読み込まれます。