使用命名空间的区别(std:: vs ::std::)
Difference in using namespace (std:: vs ::std::)
using ::std::...;
VS
using std::...;
有区别吗?如果有,是哪一个?
我看到了这个:
using ::std::nullptr_t;
这让我很奇怪。
发件人:http://en.cppreference.com/w/cpp/language/using_declaration
Using-declaration introduces a member of another namespace into
current namespace or block scope
因此,如果您当前的作用域已经有同名的class,那么您引入的那个和您当前namespace/block中的那个会产生歧义。
using 声明只是 using 指令的一个子集。 using 指令定义如下 (http://en.cppreference.com/w/cpp/language/namespace):
From the point of view of unqualified name lookup of any name after a
using-directive and until the end of the scope in which it appears,
every name from namespace-name is visible as if it were declared in
the nearest enclosing namespace which contains both the
using-directive and namespace-name.
因此,您可以考虑这两个显示可能出现的问题的示例。
它可以防止共享相同名称的名称空间之间的歧义(示例 1)以及 class 个不同名称空间中的名称之间的歧义(示例 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
声明。在全局命名空间范围内不会有任何区别。但是,如果您有
这样的代码
#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 命名空间 -> 向量,否则它不会编译
在您的情况下,很可能没有区别。不过一般来说,区别如下:
using A::foo;
从 当前 范围解析 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
和 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
命名空间绝对不是一个好习惯。
using ::std::...;
VS
using std::...;
有区别吗?如果有,是哪一个?
我看到了这个:
using ::std::nullptr_t;
这让我很奇怪。
发件人:http://en.cppreference.com/w/cpp/language/using_declaration
Using-declaration introduces a member of another namespace into current namespace or block scope
因此,如果您当前的作用域已经有同名的class,那么您引入的那个和您当前namespace/block中的那个会产生歧义。
using 声明只是 using 指令的一个子集。 using 指令定义如下 (http://en.cppreference.com/w/cpp/language/namespace):
From the point of view of unqualified name lookup of any name after a using-directive and until the end of the scope in which it appears, every name from namespace-name is visible as if it were declared in the nearest enclosing namespace which contains both the using-directive and namespace-name.
因此,您可以考虑这两个显示可能出现的问题的示例。
它可以防止共享相同名称的名称空间之间的歧义(示例 1)以及 class 个不同名称空间中的名称之间的歧义(示例 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
声明。在全局命名空间范围内不会有任何区别。但是,如果您有
#include <iostream>
#include <vector>
namespace my_namespace {
namespace std {
class vector {
};
}
using std::vector;
}
int main()
{
my_namespace::vector<int> v;
}
除非您通过声明 using ::std::vector
.
在您的情况下,很可能没有区别。不过一般来说,区别如下:
using A::foo;
从 当前 范围解析 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
和 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
命名空间绝对不是一个好习惯。