在C ++ Primer 5th中,第13.3节:
非常谨慎的读者可能想知道为什么swap中的using声明不会隐藏HasPtr版本的swap(6.4.1)的声明。我们将在18.2.3中解释为什么此代码有效的原因。
以下是示例代码:
void swap(HasPtr &lhs, HasPtr &rhs)
{...}
void swap(Foo &lhs, Foo &rhs)
{
using std::swap;
swap(lhs.h, rhs.h);
}
确实,我想知道为什么using std::swap
不会隐藏void swap(HasPtr &lhs, HasPtr &rhs)
范围内的void swap(Foo &lhs, Foo &rhs)
?相反,似乎std::swap
函数和void swap(HasPtr &lhs, HasPtr &rhs)
正在重载。
这与以下陈述相反(引自C ++ Primer 5th,第6.4.1节):
如果我们在内部作用域中声明一个名称,该名称将隐藏在外部作用域中声明的名称的使用。名称不会在范围内重载。
让我们考虑以下例子:
#include<iostream>
namespace a{
void f(int a){ std::cout<< "a::f(int)";}
}
void f(double a){ std::cout<< "f(double)";}
int main(){
using a::f;
f(1.11);
}
在这种情况下,当我们使用using a::f
时,它会隐藏外部作用域中的函数void f(double a)
。因此,我们得到以下输出
a::f(int)
这意味着此处使用了函数void f(int a)
,虽然void f(double a)
会更好地匹配(但它是隐藏的)。
总而言之,似乎如此
(1)using std::swap
重载第一种情况下外部作用域中的所有swap
函数
(2)using a::f
隐藏第二种情况下外部作用域中的所有f
函数
我的问题是,为什么会出现这种差异?
顺便说一下,这与Function hiding and using-declaration in C++有关,其中的所有答案都声称所有掉期功能都是超载而没有解释原因,所以我在这里打开另一个问题。
答案 0 :(得分:1)
使用时
using a::f;
您将a::f
的声明带到声明性区域的范围内。 声明区域部分是关键所在。
在您的情况下,它是main
的声明性区域。 f
中没有main
的其他声明。因此,f
会解析为a::f
。
要从main显示a::f
和全局f
,请使用:
using a::f;
void f(double a){ std::cout<< "f(double)";}
如果您这样做,a::f
和全球f
都可用于main
。