AG - 4.02.名前空間 Editorial /

Time Limit: 0 msec / Memory Limit: 0 KB

前のページ | 次のページ

キーポイント

  • 名前空間によって、名前の衝突を避けることができる
  • 名前空間の定義は以下のように行う
namespace 名前空間名 {
  // 内容
}
  • 名前空間内の変数や関数にアクセスするには名前空間名::によって名前空間を指定する
  • 名前空間はネストすることができる
  • using namespace 名前空間名;によって名前空間名::の指定を省略することができる
    • STLの関数や構造体はstd名前空間内に定義されている
    • using namespace std;std::を省略するためもの

名前空間

関数や構造体、グローバル変数の名前の衝突を避けるために、名前空間を定義することができます。

次のプログラムでは、名前空間Aと名前空間Bを定義し、それぞれの内部でfという関数を定義しています。

#include <bits/stdc++.h>
using namespace std;

// 名前空間A
namespace A {
  void f() {
    cout << "namespace A" << endl;
  }
}
// 名前空間B
namespace B {
  void f() {
    cout << "namespace B" << endl;
  }
}

int main() {
  A::f();  // 名前空間A内の関数fの呼び出し
  B::f();  // 名前空間B内の関数fの呼び出し
}
実行結果
namespace A
namespace B

名前空間を分けることで、このように同名の関数を定義することが出来るようになります。

関数を呼び出す時はA::f()のように、関数名の前に名前空間を明示します。

名前空間の内部では、関数の定義、構造体の定義、グローバル変数の定義などが行なえます。

名前空間の定義

名前空間を定義するには次のように書きます。

namespace 名前空間名 {
  // 内容
}

名前の解決

名前空間の内部に定義した関数や変数にアクセスするには、次のように名前空間名を指定します。

名前空間::関数名
名前空間::グローバル変数名
名前空間::構造体名

名前空間のネスト

名前空間をネストすることもできます。

#include <bits/stdc++.h>
using namespace std;

namespace A {
  namespace B{
    void f() {
      cout << "A::B::f" << endl;
    }
  }
  void f() {
    cout << "A::f" << endl;
  }
}

int main() {
  A::f();
  A::B::f();
}
実行結果
A::f
A::B::f

using namespace

using namespace 名前空間名;と書くことによって、そのスコープ内において名前空間の指定を省略することができます。

#include <bits/stdc++.h>
using namespace std;

namespace A {
  void f() {
    cout << "A::f" << endl;
  }
}

int main() {
  using namespace A;
  f(); // A::f();と書くのと同じ
}
実行結果
A::f

using namespace std;

ここまでの説明で、プログラムの2行目に書いていたusing namespace std;の意味を理解することができます。

STLの関数や構造体は、stdという名前空間の内部に定義されています。 そのため、本来はSTLの機能を使うには名前の指定にstd::を前置する必要があります。

using namespace std;を書くことによってstd::の指定を省略出来るようになります。

using namespace std;は小さな規模のプログラムを書く際には便利ですが、 規模が大きくなると名前の衝突を避けることが大変になるため、 グローバルなスコープにusing namespace std;を書くのは避けるべきです。

std::を前置すれば、using namespace std;を書かずにプログラムを書くことができます。

using namespace stdを使わない例
#include <bits/stdc++.h>

int main() {
  std::vector<int> a = {3, 4, 1, 2};
  std::sort(a.begin(), a.end());
  for (int i = 0; i < a.size(); i++) {
    std::cout << a.at(i) << std::endl;
  }
}
実行結果
1
2
3
4

細かい話

名前空間のエイリアス

名前空間をネストした場合の指定や、長い名前空間名に別名を付けることができます。

#include <bits/stdc++.h>
using namespace std;

namespace A {
  namespace B {
    namespace C {
      void f() {
        cout << "A::B::C::f" << endl;
      }
    }
  }
}

namespace too_long_name {
  void f() {
    cout << "too_long_name::f" << endl;
  }
}


int main() {
  namespace abc = A::B::C;
  abc::f();

  namespace s = too_long_name;
  s::f();
}
実行結果
A::B::C::f
too_long_name::f

前のページ | 次のページ