この記事のポイント

  • ヘッダーファイル内のusing namespaceがなぜ危険なのかを整理する
  • レビューで確認すべき依存汚染リスクを把握する
  • 設計品質を守るレビュー観点を身につける

using namespaceは便利に見えますが、
ヘッダーファイルに書くと設計の汚染を静かに広げてしまいます。
レビューアーは、構文そのものよりも 依存汚染の広がり を意識して確認したいところです。


1. まずusing namespaceとは何をしているのか?

1-1. 名前空間(namespace)の役割

C++では型や関数の名前が衝突しないように、namespaceで整理します。

namespace Logger {
  void LogInfo(const std::string& message);
}

利用する側は、このnamespace名を付けて呼び出します。

Logger::LogInfo("message");

1-2. using namespace とは?

この名前空間名の指定を省略できる構文です。

using namespace Logger;

LogInfo("message");  // Logger:: を省略

1-3. 一見便利に見えるが…

  • 名前解決がグローバルに拡散される
  • どのnamespaceの名前なのかが曖昧になる
  • 名前衝突事故が起きやすくなる

2. ヘッダーファイル内で危険になる理由

2-1. ヘッダーは貼り付け構造

ヘッダーファイルは読み込まれた翻訳単位(ソースファイル)に貼り付けられます。

// ApiRequestLog.h
using namespace std;

struct ApiRequestLog {
    int requestId;
    string endpoint;  // 実はstd::string
};

→ このヘッダーをインクルードした先でも、stdのusing namespace効果が残る状態になります。


2-2. 翻訳単位全体が汚染される

#include "ApiRequestLog.h"

// stringが裸で使えてしまう
string data;

インクルードした時点で、全体にnamespace stdが適用された状態になります。


2-3. 名前衝突が発生しやすくなる

例えば他のヘッダーが独自のstring型を持っていたら?

namespace Legacy {
  struct string { ... };
}

どのstringを使うべきか曖昧になり、コンパイラエラーが発生します。


3. 実際のレビュー指摘例

事故例1:標準ライブラリ汚染

// ApiRequestLog.h
using namespace std;
@Reviewer
ヘッダーファイルでのusing namespace stdは禁止です。依存汚染が全翻訳単位に波及します
struct ApiRequestLog { int requestId; string endpoint; string clientIp; };

改善例

#pragma once

#include <string>

struct ApiRequestLog {
    int requestId;
    std::string endpoint;
    std::string clientIp;
};

事故例2:自作namespace汚染

namespace Logger {
  void LogError(const std::string& msg);
}

// ApiRequestLog.h
using namespace Logger;
@Reviewer
Loggerのnamespaceも全翻訳単位へ拡散してしまいます。明示呼び出しに修正してください
struct ApiRequestLog { int requestId; };

改善例

#pragma once

namespace Logger {
  void LogError(const std::string& msg);
}

struct ApiRequestLog {
    int requestId;
};

4. レビューで意識したい観点整理

観点 確認ポイント
汚染伝播 using namespaceがヘッダーファイル内にないか
翻訳単位波及 インクルード先全体に影響していないか
命名衝突 別ライブラリとの名前衝突リスクがないか
明示呼び出し慣習 namespace名を適切に明示しているか
CI統制 自動検出が整備されているか
PR文化 人間レビューでも確実に確認できているか

5. PlantUMLで整理する依存汚染

UML Diagram
  • using namespaceが依存構造を静かに隠してしまう
  • 図にすると依存汚染が視覚化しやすくなります

6. CIでの自動検出

clang-tidy利用

Checks: '-*,google-build-using-namespace'
  • ヘッダーファイル内のusing namespaceを検出可能

grepベースのシンプル検出

find include/ -name '*.h' | xargs grep 'using namespace'
  • 機械的に全ヘッダーをチェックできる

PR文化の徹底

  • ヘッダーでのusing namespace禁止はレビュー文化として定着させる

7. まとめ

ヘッダーファイル内でのusing namespaceは原則使わない方針が基本です。

  • ✅ 汚染伝播を防ぐ
  • ✅ 翻訳単位間の依存波及を防ぐ
  • ✅ 命名衝突リスクを最小化する

レビューアーは単に構文ルールとして指摘するだけでなく、
「依存構造がどう崩れてしまうか?」
を読み取って設計レビューできる視点を養うのが実務的なレビュー力です。