使用命名空间 (std:: vs ::std::) 的区别

Difference in using namespace (std:: vs ::std::)

本文关键字:std 区别 vs 命名空间      更新时间:2023-10-16
using ::std::...;

using std::...;

有区别吗?如果是,是哪一个?

我看到了这个:

using ::std::nullptr_t;

这让我很纳闷。

在您的情况下,很可能没有区别。但是,通常,区别如下:

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!)
}

如果您位于另一个具有自己的嵌套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命名空间绝对不是一个好习惯。

发件人: http://en.cppreference.com/w/cpp/language/using_declaration

using-声明将另一个命名空间的成员引入到 当前命名空间或块范围

因此,如果当前作用域已经具有同名的类,则引入的类与当前命名空间/块中的类之间存在歧义。

using

声明只是 using 指令的子集。using 指令定义如下 (http://en.cppreference.com/w/cpp/language/namespace(:

从非限定名称查找的角度来看,在 using-指令,直到它出现的范围的末尾, 命名空间名称中的每个名称都是可见的,就好像它是在 最近的封闭命名空间,其中包含 使用指令和命名空间名称。

因此,您可以考虑这两个显示可能出现的问题的示例。

它可以防止共享相同名称的命名空间之间的歧义(示例 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>
}

这取决于您使用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 命名空间 -> 向量,否则它不会编译。