ABu
ABu

Reputation: 12249

ADL lookup inside a class (template) member function body

struct B {};
struct C : B {};
void f(B){} // worse match than A::f<C>

struct A {
    template<class T>
    void f(T v) {
        f(v); // #1
    }
};

int main()
{
    A{}.f(C{});
}

Activating ADL lookup in line #1 is as simple as

{
    using ::f;
    f(v);
}

I think the rule that makes the code fail without the using directive is:

[basic.lookup.argdep]/3 Let X be the lookup set produced by unqualified lookup and let Y be the lookup set produced by argument dependent lookup (defined as follows). If X contains

  • (3.1) a declaration of a class member, or
  • (3.2) a block-scope function declaration that is not a using-declaration, or
  • (3.3) a declaration that is neither a function nor a function template

then Y is empty. [...]

So, since a call to f found by non-ADL lookup will find A::f, which is a class member, overloads found by ADL-lookup are discarded.

Which C++ rule allows to ignore the restriction in 3.1 with the using declaration, to make the above code compile?

I think I'm completely misunderstanding the context where the rule [basic.lookup.argdep]/3 must be applied, or maybe I have a bigger and hidden hole in my understanding of the name lookup process.

Upvotes: 3

Views: 403

Answers (1)

Columbo
Columbo

Reputation: 60979

First paragraph on unqualified name lookup:

In all the cases listed in [basic.lookup.unqual], the scopes are searched for a declaration in the order listed in each of the respective categories; name lookup ends as soon as a declaration is found for the name.

In particular,

For the members of a class X, a name used in a member function body […], following the member's declarator-id, shall be declared in one of the following ways:

  • before its use in the block in which it is used or in an enclosing block ([stmt.block]), or

  • shall be a member of class X or be a member of a base class of X ([class.member.lookup]), or ...

A local (re)declaration of a name is prioritised and shadows all extrinsic declarations.

Upvotes: 5

Related Questions