Thanks for the detailed explanation. 👍

I now see the key is that the using-declaration hides the class-scope member functions. It has, in effect, changed the order of scope lookup. I missed this point.

On Sat, 29 May 2021 at 23:22, Ville Voutilainen <ville.voutilainen@gmail.com> wrote:
And for what it's worth, the rule is at
http://eel.is/c++draft/basic.lookup.argdep#1

Let's run through it:

>unqualified lookup ([basic.lookup.unqual]) for the name in the unqualified-id does not find any
>declaration of a class member, or

Lookup doesn't find the member any more, because it finds the
using-declaration and stops. So now ADL
is enabled.

>function declaration inhabiting a block scope, or

..and wasn't disabled because we wrote a using-declaration, not a
block-scope function declaration..

>declaration not of a function or function template

..and since we did declare a function, ADL remains enabled. If I do
using swap = int; in CompletelyUnrelated,
ADL is disabled because the using-declaration declares a non-function.
But as long as it declares a function,
even if non-viable, ADL is enabled, and is not disabled by finding the member.

Disclaimer: I'm no name lookup expert, but this seems like a plausible
explanation of how the rule works. :P


--
Yongwei Wu
URL: http://wyw.dcweb.cn/