- 为什么我不能在没有 using 声明的情况下调用 swap?
我们从最近的封闭范围开始,向外移动,直到找到一些东西。有了这个:
void H::swap(H &rhs)
{
swap(*this, rhs);
}
不合格swap
finds H::swap()
。然后我们进行依赖于参数的查找。但规则是,从[基本.lookup.argdep] http://eel.is/c++draft/basic.lookup#basic.lookup.argdep-3:
Let X是由不合格查找(3.4.1)产生的查找集,并令Y是产生的查找集
参数相关查找(定义如下)。如果X包含
— 集体成员的声明,或
— 块作用域函数声明不是使用声明, or
— 既不是函数也不是函数模板的声明
then Y是空的。否则Y是在与参数类型关联的命名空间中找到的声明集,如下所述。 [...]
由于非限定查找集找到类成员,因此参数相关查找集为空(即,它没有找到swap(H&, H&)
).
- 为什么会调用我的定义的交换而不是STL中的交换
H::swap
?
当您添加:
void H::swap(H &rhs)
{
using std::swap;
swap(*this, rhs);
}
现在不合格swap
finds std::swap()
and not H::swap()
,因为前者是在更内部的范围内声明的。using std::swap;
不符合上述规则中的任何条件,这将导致Y为空(它不是类成员,它is a 使用声明,它是一个函数模板)。因此,参数相关的查找集确实包含在关联的命名空间中找到的声明 - 其中包括swap(H&, H&)
(since H
位于全局命名空间中)。我们最终得到了两个重载候选者 - 你的是首选,因为它是非模板。
See 谢奥的回答 https://stackoverflow.com/a/6380882/2069064关于将交换添加到您的班级的首选方式。基本上,你想写:
struct H {
friend void swap(H&, H&) { ... }
};
这将由 ADL 找到(并且只能由 ADL 找到)。然后每当有人calls交换正确:
using std::swap;
swap(a, b);
查找会在适当的地方找到您的。