C++ 存在重载命名空间函数时是否需要std::限定符?
如果我有一些代码,比如:C++ 存在重载命名空间函数时是否需要std::限定符?,c++,c++11,name-lookup,C++,C++11,Name Lookup,如果我有一些代码,比如: using namespace std; namespace myNamespace { vector<float> sqrt( vector<float> v ) { return v; } void func() { vector<float> myVec = { 1, 2, 3, 4 }; std::cout << sqrt( myVec )[0] <
using namespace std;
namespace myNamespace
{
vector<float> sqrt( vector<float> v ) { return v; }
void func()
{
vector<float> myVec = { 1, 2, 3, 4 };
std::cout << sqrt( myVec )[0] << std::endl;
float myFloat = 4.0f;
std::cout << sqrt( myFloat ) << std::endl; // need to use std::sqrt()
}
}
使用名称空间std;
名称空间myNamespace
{
向量sqrt(向量v){返回v;}
void func()
{
向量myVec={1,2,3,4};
std::cout您可以通过myNamespace
中的语句使用std::sqrt;
将std::sqrt
引入您的命名空间:
namespace myNamespace
{
vector<float> sqrt( vector<float> v ) { return v; }
using std::sqrt;
...
名称空间myNamespace
{
向量sqrt(向量v){返回v;}
使用std::sqrt;
...
<> P>编译器在代码> STD::CUT C++中选择适当的<代码> > >代码,不关心参数类型,只有名称是重要的。当编译器寻找一个名为“代码> Sqrt”的函数时,它总是首先找到你的版本(因为查找从封闭的命名空间开始),然后停在那里。
您必须通过在命名空间中使用指令将
std::
中的名称引入作用域来帮助编译器:
namespace myNamespace
{
using std::sqrt
...
}
然后,将执行标准重载解析以区分sqrt
和,并选择要调用的正确sqrt
函数
为了避免任何歧义,您应该始终限定名称(std::sqrt
或myNamespace::sqrt
)
注意事项:
- 正如Simple所指出的,在第一种情况下允许名称查找(因为
vector
在std::
中),但它不会改变您所面临的问题
- 在
std::
中声明自己的sqrt
函数是一个非常糟糕的主意(标准禁止,模板专门化除外)
在std
名称空间中声明您自己的函数肯定是错误的。您可以在全局名称空间中声明它,因为您出于某种原因在其中转储了std
。或者您可以将使用std::sqrt;
添加到您的名称空间中,与sqrt
一起。我只需正确限定名称。您还可以不要使用使用名称空间somethingssomethingssomethingssomethingssomethingssomethingssomething
并始终使用std::前缀,避免像这样的废话。有没有办法将所有std::名称引入当前名称空间?比如使用std:*?它确实关心参数类型。在对sqrt
的第一次调用中,编译器将同时找到这两个myNamespace::sqrt
和std::sqrt
通过ADL(因为vector
在std
中)。它只选择myNamespace::sqrt
,因为它更匹配。