TAGS :Viewed: 10 - Published at: a few seconds ago

[ Why f1 is found but f2 not? ]

Following codes are in two source files.

First:

namespace A {
    // two friends; neither is declared apart from a friend declaration
    // these functions implicitly are members of namespace A
    class C {
        friend void f2();           // won’t be found, unless otherwise declared
        friend void f1(const C&);   // found by argument-dependent lookup
    };
}
int main()
{
    A::C obj;
    f1(obj);        // ok: find A::f through the friend declaration in A::C
    A::f2();        // no member named f2 in namespace A
}

and the second:

#include <iostream>
namespace A {
    class C;
    void f1(const C&) {
        std::cout << 1;
    }
    void f2() {
        std::cout << 2;
    }
}

The first piece of code is copied from C++ primer, the only difference is C++ primer call f2() without prefix the namespace. The second piece is my complement. I wanna know now that f1 and f2 implicitly are members of namespace A, why A::f2() is still wrong while f1(obj) can be found by ADL?

Answer 1


This is the rule, found in 7.3.1.2, that causes A::f2() to fail:

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. The friend declaration does not by itself make the name visible to unqualified lookup (3.4.1) or qualified lookup (3.4.3).

Answer 2


In the first block of code, f2 is in the lexical scope of A::C, i.e. the name is visible within the scope of A::C. It is not visible outside A::C.

To make f2 visible outside the scope of A::C, you'll need to declare or define it in A.