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

gsa*_*ras 30 c++ scope namespaces using c++11

using ::std::...;
Run Code Online (Sandbox Code Playgroud)

VS

using std::...;
Run Code Online (Sandbox Code Playgroud)

有差异吗?如果是的话,哪一个?

我看到了这个:

using ::std::nullptr_t;
Run Code Online (Sandbox Code Playgroud)

这让我很好奇.

and*_*ras 34

在您的情况下,很可能没有区别.但是,一般来说,差异如下:

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!)
}
Run Code Online (Sandbox Code Playgroud)

  • 编写宏时,这种差异非常重要.无论开发人员使用宏,都会扩展宏.宏不能假设`std`正好在它想要的地方,因此宏通常会使用`:: std`来确保宏没有任何意外的惊喜. (4认同)

Pet*_*etr 10

如果你在另一个拥有自己的嵌套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
}
Run Code Online (Sandbox Code Playgroud)

虽然绝对不是一个拥有嵌套std命名空间的好习惯.

  • @gsamaras,不仅是更全局的,而且是(唯一的)绝对全局的,不在任何地方嵌套. (4认同)

bku*_*ytt 8

来自:http://en.cppreference.com/w/cpp/language/using_declaration

Using-declaration将另一个名称空间的成员引入当前名称空间或块作用域

因此,如果您当前的作用域已经有一个具有相同名称的类,则在您引入的类和当前名称空间/块中的类之间将存在歧义.

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

从使用指令之后的任何名称的非限定名称查找的角度来看,直到它出现的作用域的结尾,来自namespace-name的每个名称都是可见的,就好像它是在最近的包含名称空间中声明的那样, 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::
}
Run Code Online (Sandbox Code Playgroud)

考虑这个例子,它展示了人们避免使用的原因 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>
}
Run Code Online (Sandbox Code Playgroud)


Ros*_*lav 5

这取决于您使用using声明的位置.在全局命名空间范围内,没有区别.但是,如果你有像这样的代码

#include <iostream>
#include <vector>

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

    using std::vector;
}

int main()
{
    my_namespace::vector<int> v;
}
Run Code Online (Sandbox Code Playgroud)

除非您通过声明通知编译器在您的声明中搜索全局命名空间 - > std namespace - > vector,否则它将无法编译using ::std::vector.

  • 另一方面,人们向源添加额外的命名空间`std`应该被解雇.这比让其他人在所有地方都写`:: std ::`容易得多. (2认同)