使用命名空间的区别(std:: vs ::std::)[重复]

Posted

技术标签:

【中文标题】使用命名空间的区别(std:: vs ::std::)[重复]【英文标题】:Difference in using namespace (std:: vs ::std::) [duplicate] 【发布时间】:2016-01-11 04:14:24 【问题描述】:
using ::std::...;

VS

using std::...;

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

我看到了这个:

using ::std::nullptr_t;

这让我想知道。

【问题讨论】:

只有当其他人将另一个std::nullptr_t 添加到您项目内的嵌套命名空间时,您才需要编写::std::nullptr_t。或者你可以让你的经理与那个人进行一次认真的谈话。 顺便说一句,namespace C14_compatibility namespace std template <typename T> using decay_t = typename decay<T>::type; using namespace C14_compatibility; 似乎是一种可能的用法。 或者实际上,当您的编译器不支持您要使用的 C++ 标准,或者它支持但您需要在某些地方自己实现时。 @chuex 同意,但这里的问题本身和答案似乎要好一些。 (即使我没有写出接受的答案,我可能也会写同样的内容。至少我希望如此......) @gsamaras:有点遗憾你删除了你的元问题......但他并没有说你愚蠢。我个人不会为此烦恼;不要生气。 【参考方案1】:

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

Using-declaration 将另一个命名空间的成员引入 当前命名空间或块范围

因此,如果您当前的作用域已经有一个同名的类,那么您引入的类与您当前命名空间/块中的类之间就会有歧义。

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

从非限定名称查找的角度来看,a 之后的任何名称 使用指令,直到它出现的范围结束, 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>

【讨论】:

在这种情况下如何使用 using 指令使其与问题一致? 通常这是对的,但这个问题是关于来自命名空间的using 类型,而不是整个命名空间! @anderas using 声明和 using 指令之间的区别并没有那么大。您可以简单地将其视为一个将单个类型引入当前范围,另一个将所有类型引入当前范围。【参考方案2】:

这取决于您使用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 的人应该被解雇。这比让其他人到处写::std:: 要容易得多。 @BoPersson 当然 :) 我只是在说明差异。写::std::...可能只是开发者的偏好。 @BoPersson:我在 OP 的问题中添加了评论,这似乎是在用户命名空间中包含 namespace std 的可行理由。【参考方案3】:

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

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

【讨论】:

这个区别在编写宏时非常重要。宏在开发人员使用的任何地方展开。宏不能假设std 准确无误地去它想要的地方,所以宏会经常使用::std 来确保宏没有任何意外的惊喜。【参考方案4】:

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

【讨论】:

所以::std:: 说要采用更全局的std命名空间?哦,安德烈亚斯在他的回答中说得很清楚,不过谢谢+1。 @gsamaras,不仅是更全局的,而且是(唯一的)绝对全局的,不嵌套在任何地方。

以上是关于使用命名空间的区别(std:: vs ::std::)[重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用std命名空间

std::thread 不是使用 Eclipse Kepler MinGW 命名空间 std 的成员

c++中命名空间std的函数都有哪些

命名空间“std”中没有名为“size”的成员

为啥 rand() 编译时不包含 cstdlib 或使用命名空间 std?

命名空间“std”中没有名为“shared_ptr”的类型