Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Argument dependent lookup for friend functions

Consider the following:

namespace N {
    struct A { };

    struct B {
        B() { }
        B(A const&) { }
        friend void f(B const& ) { }
    };
}

int main() {
    f(N::B{}); // ok
    f(N::A{}); // error
}

In the first case, the case succeeds - we consider the associated namespaces of N::B and find N::f(B const&). Great.

The second case fails. Why? According to [namespace.memdef]:

If a friend declaration in a non-local class first declares a class, function, class template or function template the friend is a member of the innermost enclosing namespace. [...] If a friend function or function template is called, its name may be found by the name lookup that considers functions from namespaces and classes associated with the types of the function arguments (3.4.2).

The associated namespace of N::A is N, of which f is a member, so why is it not found by lookup?

like image 584
Barry Avatar asked Mar 16 '16 00:03

Barry


People also ask

What is argument-dependent lookup why it is useful?

argument-dependent lookup (ADL) These function names are looked up in the namespaces of their arguments in addition to the scopes and namespaces considered by the usual unqualified name lookup. Argument-dependent lookup makes it possible to use operators defined in a different namespace.

How does ADL work C++?

In the C++ programming language, argument-dependent lookup (ADL), or argument-dependent name lookup, applies to the lookup of an unqualified function name depending on the types of the arguments given to the function call.

What is unqualified call C++?

A function call expression such as func(a,b,c) , in which the function is named without the :: scope operator, is called unqualified.


1 Answers

It's because f is not declared in an associated class. B is an associated class when the argument is of type B, but not when the argument is of type A.

I quote from [basic.lookup.argdep]/4, emphasis mine:

When considering an associated namespace, the lookup is the same as the lookup performed when the associated namespace is used as a qualifier (3.4.3.2) except that:

— Any using-directives in the associated namespace are ignored.

— Any namespace-scope friend functions or friend function templates declared in associated classes are visible within their respective namespaces even if they are not visible during an ordinary lookup (11.3).

— All names except those of (possibly overloaded) functions and function templates are ignored.

like image 118
Brian Bi Avatar answered Sep 22 '22 12:09

Brian Bi