web-dev-qa-db-ja.com

C ++では、「名前空間エイリアス」とは何ですか?

C++の「名前空間エイリアス」とは何ですか?どのように使用されますか?

144
Martin B

名前空間エイリアスは、別の短い名前で長い名前空間名を参照する便利な方法です。

例として、using namespaceディレクティブなしでBoostのuBLASの数値ベクトルを使用したいとします。毎回完全な名前空間を記述するのは面倒です:

boost::numeric::ublas::vector<double> v;

代わりに、boost::numeric::ublasのエイリアスを定義できます。これを単にublasに短縮したい場合:

namespace ublas = boost::numeric::ublas;


ublas::vector<double> v;
169
Martin B

簡単に言えば、#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はすでにクラス名です。

7
user2168377

また、名前空間のエイリアスと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;
    }
}

上記の有用性は制限される場合がありますが、目的にかなうはずです。

(上記で見逃したかもしれないタイプミスに対する謝罪。)

2
Justin Time

このトピックの詳細 http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n

次のような名前空間名のエイリアスを選択することがすべてです。

namespace SHORT = NamespaceFirst::NameSpaceNested::Meow

その後、typedefすることができます

typedef SHORT::mytype

の代わりに

typedef NamespaceFirst::NameSpaceNested::Meow::mytype

この構文は名前空間でのみ機能し、クラス、namespace NAME =の後の型を含めることはできません

1
kiriloff

名前空間は、名前の競合を防ぐために使用されます。

例えば:

namespace foo {
    class bar {
        //define it
    };
}

namespace baz {
    class bar {
        // define it
    };
}

これで、ネームスペースのおかげで、まったく異なる2つのクラスの名前バーができました。

表示する「名前空間の使用」は、その名前空間内のクラスを使用するために名前空間を指定する必要がないようにするためです。つまり、std :: stringはstringになります。

私のリソース: https://www.quora.com/What-is-namespace-in-C++-1

0
mai