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

Why name lookup can't find std::swap when a base class has a swap function in C++?

我有我的代码的副本

#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

据我了解 swapA::handle() 内调用将触发非限定查找,因为它会在父 class 中找到交换名称,这是一个函数,依赖于参数的名称查找(ADL) 将被调用。 为什么这里的 ADL 找不到 std::swap 并使用它?相反,它会尝试调用父级的交换。

我在这里缺少什么?


Platform/Compiler:红帽 6.7/GNU 5.3.0

Platform/Compiler: Windows 10/ visual studio 2015

对于unqualified name lookup:

name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined.

所以名字swap首先在classA中检查,没有找到,然后在classParent中检查,找到了,然后名称查找停止。 std::swap 引入全局范围将根本找不到。

Why the ADL here can't find the std::swap and use it ?

您将 long 传递给 swap,而 ADL 适用于 class 类型,但不适用于基本类型。

  1. For arguments of fundamental type, the associated set of namespaces and classes is empty

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

First, the argument-dependent lookup is not considered if the lookup set produced by usual unqualified lookup contains any of the following:

  1. a declaration of a class member

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