C++ 使用名称空间的差异(std::vs::std:)

C++ 使用名称空间的差异(std::vs::std:),c++,c++11,scope,namespaces,using,C++,C++11,Scope,Namespaces,Using,VS 有区别吗?如果有,哪一个 我看到了: using std::...; 这让我好奇。来自: 使用声明将另一个命名空间的成员引入 当前命名空间或块范围 因此,如果您当前的作用域已经有一个同名的类,那么您引入的类和当前命名空间/块中的类之间将存在歧义 using声明只是using指令的子集。using指令定义如下(): 从非限定名称查找的角度来看 使用指令,直到它出现的范围结束, 命名空间名称中的每个名称都是可见的,就好像它是在 最近的封闭命名空间,其中包含 使用指令和命名空间名称 因此,您可

VS

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

我看到了:

using std::...;
这让我好奇。

来自:

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

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

using声明只是using指令的子集。using指令定义如下():

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

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

它可以防止共享相同名称的名称空间之间的歧义(示例1)以及不同名称空间中的类名之间的歧义(示例2)

考虑这个例子,它展示了人们为什么不使用
名称空间std

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::
}
使用名称空间std;
模板
类向量
{ };
int main()
{
向量v;//您想要哪一个?不明确
::vector v_global;//全局一
::std::vector v_std;//std::vector
}

这取决于在何处使用
声明。在全局名称空间作用域上没有区别。但是,如果您有这样的代码

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>
}
#包括
#包括
名称空间my_名称空间{
名称空间标准{
类向量{
};
}
使用std::vector;
}
int main()
{
my_名称空间::vector v;
}

它不会编译,除非您通过声明
using::std::vector

通知编译器在声明中搜索全局命名空间->std命名空间->向量。在您的情况下,很可能没有区别。但是,一般来说,区别如下:

使用A::foo
从当前作用域解析
A
,而
使用::A::foo
从根命名空间搜索
A
。例如:

#include <iostream>
#include <vector>

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

    using std::vector;
}

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

如果您在另一个具有自己嵌套的
std
命名空间的命名空间中,则
::std
std
是不同的。一个简单的例子:

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!)
}
#包括
名称空间A{
名称空间标准{

void foo(){::std::cout So
::std:
说使用更全局的std名称空间?噢,安德烈亚斯在他的回答中说得很清楚,谢谢,+1。@gsamaras,不仅是更全局的,而且是(唯一的)一个绝对是全局的,不嵌套在任何地方。另一方面,向源代码添加额外名称空间
std
的人应该被解雇。这比让其他人到处写
::std:
容易得多。@Boperson当然:)我只是在说明区别。这可能只是开发人员的偏好编写
::std::…
@BoPersson:我在OP的问题中添加了注释,这似乎是在用户名称空间中添加
名称空间std
的一个可行原因。只有当其他人在项目中的嵌套名称空间中添加另一个
std::nullptr\t
时,您才需要编写
::std::nullptr\t
。或者您可以让您的顺便说一句,
namespace C14_compatibility{namespace std{template using decay\u t=typename decay::type;}<>代码>使用命名空间C14Load兼容性;看起来是一种可能的用法。或者,当编译器不支持你想要使用的C++标准时,或者它确实需要,但在某些地方你需要自己的实现。@ CuEX同意,但是问题本身和答案看起来稍微好一点。(即使我没有写出公认的答案,我可能也会写同样的答案。至少我希望如此……)@gsamaras:很遗憾你删除了你的元问题……但他并没有说你愚蠢。我个人不会为此烦恼;不要生气。在这种情况下,如何使用using指令使其与问题一致?通常这是正确的,但这个问题是关于
使用命名空间中的类型,而不是整个名称空间!@Ander因为using声明和using指令之间的差异并没有那么大。您可以简单地将其视为一个将单个类型引入当前范围,另一个将所有类型引入当前范围。在编写宏时,这一差异非常重要。宏在开发人员使用的任何地方都会展开它。宏不能假定
std
正好到达它想要的地方,因此宏通常会使用
::std
来确保宏没有任何意外。
#include <iostream>
#include <vector>

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

    using std::vector;
}

int main()
{
    my_namespace::vector<int> v;
}
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!)
}
#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
}