Подтвердить что ты не робот

Разница в использовании пространства имен (std:: vs:: std::)

using ::std::...;

VS

using std::...;

Есть ли разница (-ы)? Если да, то какой (ы)?

Я видел это:

using ::std::nullptr_t;

что заставило меня задуматься.

4b9b3361

Ответ 1

В вашем случае, скорее всего, нет разницы. Однако, как правило, разница заключается в следующем:

using A::foo; разрешает 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!)
}

Ответ 2

Если вы находитесь внутри другого пространства имен, у которого есть собственное вложенное пространство имен std, тогда ::std и std отличаются. Простой пример:

#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.

Ответ 3

От: http://en.cppreference.com/w/cpp/language/using_declaration

Использование-объявления вводит член другого пространства имен в текущее пространство имен или область видимости

Поэтому, если ваша текущая область уже имеет класс с тем же именем, будет неопределенность между тем, который вы ввели, и тем, который находится в вашем текущем пространстве имен/блоке.

Использование объявления - это просто подмножество директивы using. Директивы использования определяются следующим образом (http://en.cppreference.com/w/cpp/language/namespace):

С точки зрения неквалифицированного поиска имени любого имени после используя-директиву и до конца области, в которой он появляется, каждое имя из имени пространства имен отображается так, как если бы оно было объявлено в ближайшего охватывающего пространства имен, которое содержит как using-directive и namespace-name.

Таким образом, вы можете рассмотреть эти два примера, которые отображают проблемы, которые могут возникнуть.

Он предотвращает неоднозначность между пространствами имен, которые имеют одно и то же имя (пример 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>
}

Ответ 4

Это зависит от того, где вы используете объявление using. В глобальной области пространства имен не будет никакой разницы. Однако, если у вас есть код типа

#include <iostream>
#include <vector>

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

    using std::vector;
}

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

он не будет компилироваться, если вы не сообщите компилятору о поиске в глобальном пространстве имен → std namespace → vector в объявлении, указав using ::std::vector.