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