This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-12-19


1906. Name lookup in member friend declaration

Section: 6.5.3  [basic.lookup.unqual]     Status: NAD     Submitter: Richard Smith     Date: 2014-03-30

According to 6.5.3 [basic.lookup.unqual] paragraph 10,

In a friend declaration naming a member function, a name used in the function declarator and not part of a template-argument in the declarator-id is first looked up in the scope of the member function's class (6.5.2 [class.member.lookup]). If it is not found, or if the name is part of a template-argument in the declarator-id, the look up is as described for unqualified names in the definition of the class granting friendship.

The corresponding specification for non-friend declarations in paragraph 8 applies the class-scope lookup only to names that follow the declarator-id. The same should be true in friend declarations.

Proposed resolution (February, 2018):

  1. Change 6.5.3 [basic.lookup.unqual] paragraph 8 as follows:

  2. For the members of a class X, a name used in a member function body, in a default argument, in a noexcept-specifier, in the brace-or-equal-initializer of a non-static data member (11.4 [class.mem]), or in the definition declaration of a class member outside of the definition of X, following the member's declarator-id32, shall be declared in one of the following ways:

  3. Delete 6.5.3 [basic.lookup.unqual] paragraph 10 and combine its example with that of paragraph 8:

  4. In a friend declaration naming a member function, a name used in the function declarator and not part of a template-argument in the declarator-id is first looked up in the scope of the member function's class (6.5.2 [class.member.lookup]). If it is not found, or if the name is part of a template-argument in the declarator-id, the look up is as described for unqualified names in the definition of the class granting friendship. [Example:

      struct A {
        typedef int AT;
        void f1(AT);
        void f2(float);
        template <class T> void f3();
      };
      struct B {
        typedef char AT;
        typedef float BT;
        friend void A::f1(AT);     // parameter type is A::AT
        friend void A::f2(BT);     // parameter type is B::BT
        friend void A::f3<AT>(); // template argument is B::AT
      };
    

    end example]

Notes from the February, 2018 teleconference:

There was some concern as to whether the added lookup for friend function declarations placed the additional lookups in the correct sequence relative to the existing lookups and whether the new specification reflects any existing practice.

Rationale (March, 2018):

After further discussion, CWG determined that the semantics described in the existing wording were the most appropriate out of the alternatives considered.