web-dev-qa-db-ja.com

名前空間の使用の違い(std :: vs :: std::)

using ::std::...;

VS

using std::...;

違いはありますか?もしそうなら、どれですか?

これを見た:

using ::std::nullptr_t;

不思議に思いました。

32
gsamaras

あなたの場合、ほとんどの場合、違いはありません。ただし、一般的に、違いは次のとおりです。

using A::foo;は、currentスコープからAを解決し、using ::A::fooルート名前空間からAを検索します。例えば:

namespace A
{
    namespace B
    {
         class C;
    }
}
namespace B
{ 
    class C;
}
namespace A
{
    using B::C; // resolves to A::B::C
    using ::B::C; // resolves to B::C
    // (note that one of those using declarations has to be
    // commented for making this valid code!)
}
34
anderas

ネストされた独自のstd名前空間を持つ別の名前空間内にいる場合は、::stdstdは異なります。簡単な例:

#include <iostream>

namespace A {
    namespace std {
        void foo() { ::std::cout << "foo" << ::std::endl;}
    }
    //using std::cout; // compile error
    using ::std::cout; //ok

    using std::foo; // ok
    //using ::std::foo; // compile error
}

ネストされたstd名前空間を持つことは絶対に良い習慣ではありませんが。

10
Petr

差出人: http://en.cppreference.com/w/cpp/language/using_declaration

Using-declarationは、別の名前空間のメンバーを現在の名前空間またはブロックスコープに導入します

したがって、現在のスコープにすでに同じ名前のクラスがある場合、導入したスコープと現在の名前空間/ブロック内のクラスの間にあいまいさが生じます。

Using宣言は、usingディレクティブのサブセットにすぎません。 usingディレクティブは次のように定義されています( http://en.cppreference.com/w/cpp/language/namespace ):

Usingディレクティブの後の任意の名前の非修飾名ルックアップの観点から、それが表示されるスコープの終わりまで、namespace-nameのすべての名前は、両方を含む最も近い囲んでいる名前空間で宣言されているかのように表示されます。 using-directiveおよびnamespace-name。

したがって、発生する可能性のある問題を表示するこれら2つの例を検討できます。

これにより、同じ名前を共有する名前空間間のあいまいさ(例1)や、異なる名前空間のクラス名間のあいまいさ(例2)が防止されます。

namespace A
{
    namespace B
    {
        struct my_struct {};
    }
}

namespace B
{
    struct my_struct {};
}

using namespace A; // removing this line makes B:: resolve to the global B::

int main()
{
    ::B::my_struct; // from global, will not pick A::B::

    B::my_struct; // error: 'B' is ambiguous, there is A::B:: and B::
}

人々がusing namespace std;の使用を避ける理由を示すこの例を考えてみましょう。

using namespace std;

template <typename T>
class vector
{ };

int main()
{
    vector<int> v; // which one did you want? ambiguous
    ::vector<int> v_global;     // global one
    ::std::vector<int> v_std;   // std::vector<T>
}
8
bku_drytt

using宣言を使用する場所によって異なります。グローバル名前空間スコープでは、違いはありません。ただし、次のようなコードがある場合

#include <iostream>
#include <vector>

namespace my_namespace {
    namespace std {
        class vector {
        };
    }

    using std::vector;
}

int main()
{
    my_namespace::vector<int> v;
}

using ::std::vectorを指定して、宣言内のグローバル名前空間-> std名前空間->ベクトルを検索するようコンパイラーに通知しない限りコンパイルされません。

5
Rostislav