为什么使用std :: swap不会隐藏外部作用域中的其他交换函数

时间:2017-10-23 20:05:07

标签: c++ namespaces hide overloading swap

在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++有关,其中的所有答案都声称所有掉期功能都是超载而没有解释原因,所以我在这里打开另一个问题。

1 个答案:

答案 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

https://ideone.com/ySvGlP处查看它。