当基类在 C++ 中具有交换函数时,为什么名称查找找不到 std::swap?



我有一个代码中内容的副本

#include <utility>
using namespace std;
class Parent
{
public:
void swap(Parent*);
};
class A : public Parent 
{
public:
void handle();
};

void A::handle()
{
long x = 1;
long y = 2;
swap(x,y);
}

int main()
{
A v;
v.handle();
return 0;
}

错误日志:

main.cpp: In member function 'void A::handle()':
main.cpp:21:10: error: no matching function for call to 'A::swap(long int&, long int&)'
swap(x,y);
^
main.cpp:7:8: note: candidate: void Parent::swap(Parent*)
void swap(Parent*);
^
main.cpp:7:8: note:   candidate expects 1 argument, 2 provided

据我所知,A::handle()内部的swap调用将触发非限定查找,并且由于它将在作为函数的父类中找到交换名称,因此将调用参数相关名称查找(ADL)。为什么这里的ADL找不到std::swap并使用它?相反,它尝试调用Parent的交换。

我在这里缺少什么?


平台/编译器:Red hat 6.7/NGNU 5.3.0

平台/编译器:Windows 10/visual studio 2015

对于非限定名称查找:

名称查找按如下所述检查作用域,直到它至少找到一个任何类型的声明,此时查找停止,不再检查其他作用域。

因此,首先在类A中检查名称swap,但未找到,然后在类Parent中检查,找到,然后停止名称查找。引入全局范围的std::swap根本找不到。

为什么这里的ADL找不到std::swap并使用它?

longs传递给swap,而ADL处理类类型,但不处理基本类型。

  1. 对于基本类型的参数,关联的命名空间和类集为空

BTW:在这种特殊情况下,即使您更改为将std命名空间中定义的一些类类型传递给swapADL也不会被考虑。

首先,如果由通常的非限定查找生成的查找集包含以下任何内容,则不考虑参数相关查找:

  1. 类成员的声明

Parent::swap是通过通常的非限定名称查找找到的类成员,ADL仍然不会被考虑。

最新更新