【问题标题】:Difference in using namespace (std:: vs ::std::) [duplicate]使用命名空间的区别(std:: vs ::std::)[重复]
【发布时间】: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:有点遗憾你删除了你的元问题......但他并没有说你愚蠢。我个人不会为此烦恼;不要生气。

标签: c++ c++11 scope namespaces using


【解决方案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,不仅是更全局的,而且是(唯一的)绝对全局的,不嵌套在任何地方。
猜你喜欢
  • 2015-10-05
  • 2013-09-03
  • 1970-01-01
  • 1970-01-01
  • 2015-10-28
  • 2013-08-24
  • 2017-04-30
  • 1970-01-01
  • 2014-12-06
相关资源
最近更新 更多