C++ Logo

STD-DISCUSSION

Advanced search

Subject: Re: Member function, using, and ADL
From: Ville Voutilainen (ville.voutilainen_at_[hidden])
Date: 2021-05-29 10:01:43


On Sat, 29 May 2021 at 17:36, Yongwei Wu via Std-Discussion
<std-discussion_at_[hidden]> wrote:
>
> I happened to find Alan Griffiths' article ‘C++ Standards - The "swap" Problem"’ (<URL:https://accu.org/journals/overload/9/41/griffiths_466/>), and I did some tests while reading it. I was happy and surprised to find what he described seemed a non-issue now.
>
> I tested with the following code:
>
> #include <iostream>
> #include <utility>
>
> namespace Impl {
>
> struct A {
> int value;
> };
>
> void swap(A& x, A& y)
> {
> std::cout << "Impl::A::swap\n";
> std::swap(x, y);
> }
>
> }
>
> namespace App {
>
> struct Obj {
> void swap(Obj& rhs);
> Impl::A a_value;
> };
>
> void Obj::swap(Obj& rhs)
> {
> using std::swap; // NB this line
> swap(a_value, rhs.a_value);
> }
>
> void swap(Obj& lhs, Obj& rhs)
> {
> lhs.swap(rhs);
> }
>
> }
>
> int main()
> {
> App::Obj a, b;
> swap(a, b);
> }
>
> I have found out that an error will occur without the ‘using std::swap;’ line, but with it ADL will be in effect and find Impl::A::swap.
>
> The interesting thing is that I do not need to write `using Impl::swap;`—it seems any using of non-member functions will enable ADL. But I do not know why.
>
> I have looked up the C++ standard and the cppreference.com web site, but failed to find the exact paragraph that dictates this behaviour. Anyone here knows which rules in C++ make this possible?

The thing here is that you can write 'using Impl::swap;' instead of
'using std::swap;' on the "NB" line and the example still works
just fine. The problem with not having any using-declaration there is
that an unqualified call to swap will try to call the member
function itself, recursively, and lookup will look no further. ADL
would work fine for any other name without the using-declaration,
but it won't work for the name swap - unless you bring *any* function
candidate name into scope. It doesn't need to be the one called,
it doesn't even need to be viable, and ADL will be used once such a
second candidate is in scope, so as to disable the
name lookup shortcut that looks no further than the member function
itself. See this:
https://wandbox.org/permlink/qsrmhp1ddzBQgRjR


STD-DISCUSSION list run by std-discussion-owner@lists.isocpp.org

Older Archives on Google Groups