回答:
名前空間エイリアスは、長い名前空間名を別の短い名前で参照する便利な方法です。
例として、using namespace
ディレクティブなしでBoostのuBLASからの数値ベクトルを使用したいとします。名前空間全体を毎回述べるのは面倒です。
boost::numeric::ublas::vector<double> v;
代わりに、エイリアスを定義できます。boost::numeric::ublas
これを単にublas
次のように短縮したいとします。
namespace ublas = boost::numeric::ublas;
ublas::vector<double> v;
簡単に言うと、#defineは機能しません。
namespace Mine { class MyClass { public: int i; }; }
namespace His = Mine;
namespace Yours { class Mine: public His::MyClass { void f() { i = 1; } }; }
正常にコンパイルします。名前空間/クラス名の衝突を回避できます。
namespace Nope { class Oops { public: int j; }; }
#define Hmm Nope
namespace Drat { class Nope: public Hmm::Oops { void f () { j = 1; } }; }
最後の行の "Hmm:Oops"はコンパイルエラーです。プリプロセッサーはそれをNope :: Oopsに変更しますが、Nopeはすでにクラス名です。
次のような、名前空間の名前のエイリアスを選択することがすべてです。
namespace SHORT = NamespaceFirst::NameSpaceNested::Meow
その後、あなたはtypedefすることができます
typedef SHORT::mytype
の代わりに
typedef NamespaceFirst::NameSpaceNested::Meow::mytype
この構文は名前空間でのみ機能し、クラス、型の後に含めることはできません namespace NAME =
また、名前空間のエイリアスとusingディレクティブは、実行時ではなくコンパイル時に解決されることにも注意してください。(より具体的には、どちらも、現在のスコープまたはその親スコープのいずれかに特定のシンボルが見つからない場合に、名前を解決するときに他に探す場所をコンパイラーに指示するために使用されるツールです。)たとえば、これらのどちらもコンパイル:
namespace A {
int foo;
namespace AA {
int bar;
} // namespace AA
namespace AB {
int bar;
} // namespace AB
} // namespace A
namespace B {
int foo;
namespace BA {
int bar;
} // namespace BA
namespace BB {
int bar;
} // namespace BB
} // namespace B
bool nsChooser1, nsChooser2;
// ...
// This doesn't work.
namespace C = (nsChooser1 ? A : B);
C::foo = 3;
// Neither does this.
// (Nor would it be advisable even if it does work, as compound if-else blocks without braces are easy to inadvertently break.)
if (nsChooser1)
if (nsChooser2)
using namespace A::AA;
else
using namespace A::AB;
else
if (nsChooser2)
using namespace B::BA;
else
using namespace B::BB;
さて、好奇心旺盛な人は、constexpr
変数がコンパイル時にも使用されることに気づき、それらがエイリアスまたはディレクティブのいずれかと組み合わせて使用できるかどうか疑問に思っているかもしれません。私の知る限り、私はこれについて間違っているかもしれませんが、彼らはできません。異なる名前空間で同じ名前の変数を使用して動的に選択する必要がある場合は、参照またはポインタを使用する必要があります。
// Using the above namespaces...
int& foo = (nsChooser1 ? A::foo : B::foo);
int* bar;
if (nsChooser1) {
if (nsChooser2) {
bar = &A::AA::bar;
} else {
bar = &A::AB::bar;
}
} else {
if (nsChooser2) {
bar = &B::BA::bar;
} else {
bar = &B::BB::bar;
}
}
上記の有用性は限られているかもしれませんが、それは目的を果たすはずです。
(上記で見逃したかもしれないタイプミスについての私の謝罪)
名前空間は、名前の競合を防ぐために使用されます。
例えば:
namespace foo {
class bar {
//define it
};
}
namespace baz {
class bar {
// define it
};
}
これで、名前空間のおかげで、2つのクラスの名前バーが完全に異なり、別々になりました。
表示する「using namespace」は、そのネームスペース内のクラスを使用するためにネームスペースを指定する必要がないようにするためのものです。つまり、std :: stringはstringになります。