为什么使用std::swap不会在外部范围中隐藏其他交换函数
Why using std::swap does not hide other swap functions in the outer scope
在C++Primer第5版中,第13.3节:
非常细心的读者可能会想,为什么swap中的using声明没有隐藏swap的HasPtr版本(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
函数
我的问题是,为什么会有这样的差异?
顺便说一句,这与C++中的函数隐藏和使用声明有关,其中所有的答案都声称所有的交换函数都是重载的,但没有解释为什么,所以我在这里打开了另一个问题。
使用时
using a::f;
您将a::f
的声明带到声明性区域的范围中。声明性区域部分是这里的关键。
在您的情况下,它是main
的声明性区域。main
中没有f
的其他声明。因此,f
解析为a::f
。
要使a::f
和全局f
从main可见,请使用:
using a::f;
void f(double a){ std::cout<< "f(double)";}
如果执行此操作,则a::f
和全局f
对main
都可用。
看到它在工作https://ideone.com/ySvGlP.
- 为什么在全局范围内使用"extern int a"似乎不行?
- 尝试通过多个向量访问变量时,向量下标超出范围
- 错误:未在此范围内声明'reverse'
- 正在将指针转换为范围
- 使用std::transform将一个范围的元素添加到另一个范围中
- 在基于范围的for循环中使用结构化绑定声明
- 这是我尝试让用户将值输入到数组中.然后将其隐藏为大量的星号
- 如何计算数据类型的范围,例如int
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 在C++中查找范围的长度
- 如何设置一个范围来提取我想要获得的信息
- 并行用于C++17中数组索引范围内的循环
- 为左值和右值的包装器实现C++范围
- 求出有多少个数字是完美平方,而sqrt()是L,R范围内的素数
- 结构和双指针隐藏在其他结构中,多层混淆
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- pImpl、范围和隐藏数据成员
- 在C 中本地声明隐藏的封闭范围(而非全局)中访问变量
- 为什么使用std::swap不会在外部范围中隐藏其他交换函数
- 对[基本范围]的解释当非限定名称查找涉及到使用-指令时,隐藏]p2