【C++】名前空間エイリアス - 名前空間の別名を定義

C++では既存の名前空間の別名を作ることが出来ます。

名前空間エイリアス

名前空間エイリアス(namespace alias)は名前空間の別名を定義する機能です。

以下のコードは、既存の名前空間stdの別名libを定義する例です。

namespace lib = std;
// いずれも同じクラスを利用していることになる
lib::string a = "a";
std::string b = "b";

ネストされた名前空間のエイリアス

ネストされた名前空間を短縮された一つの別名として定義することも可能です。

namespace A {
  namespace B {
    void test() {}
  }
}

namespace X = A::B; // Xに短縮
X::test();

活用例

やたらと長いネームスペースを短縮する際に使うと良いです。

namespace log = c_plus_plus_dynamic_logger;

また、ネストされたネームスペースを短縮するのにもオススメです。

namespace glog = com::googie::logger::static_logger::release;

応用例

この機能は名前空間のラッパーを作るのにも役立ちます。

以下のように、デバッグ用とリリース用で異なる名前空間を適用することが可能になります。

// 開発用
namespace ns_debug {
  void log() { puts("debug"); }
}
// 本番用
namespace ns_release {
  void log() { puts("release"); }
}

#ifdef DEBUG
  namespace ns = ns_debug;
#else
  namespace ns = ns_release;
#endif

int main() {
  // 開発時と本番時で異なる挙動をとらせることが可能に
  ns::log();
}

細かな仕様

既存の名前空間の宣言領域内で同名のエイリアスを定義することは出来ません。

namespace a {}
namespace std = a; // Redefinition of 'std'

グローバル空間には既にstdが宣言されているため、名前衝突が発生してしまいます。

別の名前空間内であれば定義が可能です。

namespace a {}
int main() {
  namespace std = a; // OK
}

本機能はエイリアスを定義するだけですので、型の再定義やシンボル名の変化は起こりません。

namespace lib = std;

lib::string a = "a";
std::string b = "b";

// 型の再定義はされないため、同一の型として扱える
a = b;
lib::string c = std::string("c");
[](const std::string& s) { puts(s.c_str()); }(c);

// いずれも元の名前空間で取得される
puts(typeid(lib::string).name()); // NSt3__112basic_string...
puts(typeid(std::string).name()); // NSt3__112basic_string...
広告