C++ 我们为什么要使用“:”&引用;全局函数/对象上的运算符?
我在很多地方都见过这种方法。C++程序员通常会使用::在全局函数调用之前,操作员正确。 e、 g 为什么会这样?为什么不直接使用:C++ 我们为什么要使用“:”&引用;全局函数/对象上的运算符?,c++,syntax,C++,Syntax,我在很多地方都见过这种方法。C++程序员通常会使用::在全局函数调用之前,操作员正确。 e、 g 为什么会这样?为什么不直接使用: glGenBuffers( 1, &id ); 以避免意外的命名空间冲突。例如,如果您当前的命名空间将具有glGenBuffers,它与使用:的“good”glGenBuffers不同:,您可以指定调用全局命名空间中的glGenBuffers。 ::(范围解析)运算符用于限定隐藏名称,以便 你仍然可以使用它们。如果 命名空间范围或全局范围名称由显式 块或类
glGenBuffers( 1, &id );
以避免意外的命名空间冲突。例如,如果您当前的命名空间将具有
glGenBuffers
,它与使用:
的“good”glGenBuffers
不同:,您可以指定调用全局命名空间中的glGenBuffers
。
::(范围解析)运算符用于限定隐藏名称,以便
你仍然可以使用它们。如果
命名空间范围或全局范围名称由显式
块或类中同名的声明
::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
}
}
void方法()
{
std::cout问题是1)内部作用域中的名称隐藏外部作用域中的名称,2)使用USE指令时,函数调用可能存在歧义
例如(歧义)
#包括
使用名称空间std;
无效交换(整数和x、整数和y)
{
int tmp=x;
x=y;
y=tmp;
}
int main()
{
int x=5,y=10;
//交换(x,y);编译器错误:调用什么函数?
::swap(x,y);//调用用户定义的函数
std::swap(x,y);//调用标准函数。
}
另一个隐藏姓名的例子
#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();
}
#包括
空f*({STD::CUT显式标记范围)可以通过使用声明或依赖于参数的查找来避免意外的匹配。例如,考虑以下内容:
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
}
如果您不知道命名空间foo
中有一个bar
,或者某个对象的类型来自命名空间foo
,那么调用foo::bar
而不是::bar
可能会让您大吃一惊。范围操作符(:
)用于在2种情况下访问全局命名空间,主要是:
a) 将全局方法/变量/类型定义(从全局命名空间)导入命名空间:
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
}
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
}
#包括
使用名称空间std;
模板内联
无效掉期(T&left、T&right)
{
T tmp=左;
左=右;
右=tmp;
}
int main()
{
INTA=1,b=2;
//交换(a,b)-错误:哪个“交换”?
std::swap(a,b);//在
::交换(a,b);//我定义的那个
}
- 注意:
使用命名空间std;
不是推荐的做法
编辑
MSVC编译器提供了\u CSTD
宏(\define\u CSTD::
),这样您就可以使用使用_cstdfun;
,e.t.c,如果您愿意的话。就个人而言,我永远不会在我的代码中使用leading::。如果我有一个名称空间用重复的定义覆盖全局,那么我可能打算这么做。在不需要的时候使用::就像编写this->variable
,而不是vari启用类内函数
。
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
}
typedef unsigned int size_t;
namespace std
{
using ::size_t;
}
size_t x = 1;
std::size_t y = 2;
# 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
}