使用命名空间的区别(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
命名空间的命名空间内,则 ::std
和 std
是不同的。一个简单的例子:
#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::thread 不是使用 Eclipse Kepler MinGW 命名空间 std 的成员