我见过这种用法在各个地方。 C ++程序员经常在全局函数调用之前使用::运算符。
e.g
::glGenBuffers( 1, &id );
这是为什么?为什么不直接使用:
glGenBuffers( 1, &id );
答案 0 :(得分:4)
避免意外的命名空间冲突。例如,如果您当前的命名空间有glGenBuffers
,它会执行与" good"不同的操作。 glGenBuffers
::
glGenBuffers
您可以指定调用全局命名空间中的{{1}}。
答案 1 :(得分:2)
问题是1)内部作用域中的名称隐藏了外部作用域中的名称; 2)当使用using指令时,函数调用可能不明确。
例如(歧义)
#include <algorithm>
using namespace std;
void swap( int &x, int &y )
{
int tmp = x;
x = y;
y = tmp;
}
int main()
{
int x = 5, y = 10;
//swap( x, y ); compiler error: what function to call?
::swap( x, y ); // the user defined function is called
std::swap( x, y ); // the standard function is called.
}
隐藏姓名的另一个例子
#include <iostream>
void f() { std::cout << "::f()\n"; }
namespace MyNamespace
{
void f() { std::cout << "MyNamespace::f()\n"; }
void g() { f(); } // calls MyNamespace::f()
void h() { ::f(); } // calls ::f()
}
int main()
{
MyNamespace::g();
MyNamespace::h();
}
答案 2 :(得分:1)
正如您在此处所见C++ Scope Resolution Operator ::
::(范围解析)运算符用于限定隐藏名称 你仍然可以使用它们。如果a,您可以使用一元范围运算符 命名空间范围或全局范围名称由显式隐藏 块或类中的同名声明。
答案 3 :(得分:1)
::glGenBuffers
强制选择全局命名空间中的方法
void method()
{
std::cout << "method in global namespace";
}
class Test {
void method()
{
std::cout << "method in Test class";
}
void test()
{
method(); // method in Test class
::method(); //method in global namespace
}
}
答案 4 :(得分:1)
通过使用声明或参数相关查找,显式标记范围可以使您避免意外匹配。例如,请考虑以下事项:
namespace foo
{
class X {};
void bar(X*, int):
}
// ... much in between ...
foo::X some_object
// ... more in between ...
void bar(X*, long);
int main()
{
bar(&some_object, 42); // calls foo::bar, because it is a better match
::bar(&some_object, 42); // calls ::bar, because it is explicitly told to
}
如果您不知道名称空间bar
中有foo
,或者some_object
的名称空间为foo
,则调用{{1}而不是foo::bar
可能会让你感到意外。
答案 5 :(得分:0)
范围运算符(::
)主要用于访问全局命名空间两次:
a)将全局方法/变量/ typedef(从全局命名空间)导入命名空间:
int fun()
{
return 1;
}
namespace x
{
using ::fun;
// you cannot do `using fun`, as using requires a namespace after
// in this case, we are `using` the global namespace
}
int main()
{
std::cout << fun() + x::fun(); // prints 2
}
修改:这是由一些STL
实施完成的,例如:std::size_t
:
typedef unsigned int size_t;
namespace std
{
using ::size_t;
}
size_t x = 1;
std::size_t y = 2;
b)避免冲突:
# include <algorithm>
using namespace std;
template<class T> inline
void swap(T &left, T &right)
{
T tmp = left;
left = right;
right = tmp;
}
int main()
{
int a = 1, b = 2;
// swap(a, b) - error: which 'swap'?
std::swap(a, b); // the one in <algorithm>
::swap(a, b); // the one i defined
}
using namespace std;
不是推荐的做法。修改强>
MSVC编译器提供_CSTD
宏(#define _CSTD ::
),以便您可以根据需要使用using _CSTD fun;
,e.t.c。