2795. §[global.functions] provides incorrect example of ADL use

Section: 16.4.6.4 [global.functions] Status: C++17 Submitter: Jonathan Wakely Opened: 2016-11-09 Last modified: 2017-07-30

Priority: Not Prioritized

View all other issues in [global.functions].

View all issues with C++17 status.

Discussion:

Addresses GB 39

The example is supposed to highlight the 'otherwise specified' aspect of invoking ADL, yet there is no such specification. It is unlikely that we intend to explicitly qualify calls to operator functions, so they probably should be exempted from this restriction.

Suggested resolution:

Fix example (and referenced clause) to specify use of ADL, or exempt operators from this clause, and find a better example, probably using swap.

[2016-11-09, Jonathan comments and provides wording]

The current wording was added by DR 225.

[2016-11-10, Tim Song comments]

The "non-operator" seems to have been added at the wrong spot. The problem at issue is permission to call operator functions found via ADL, not permission for operator functions in the standard library to ADL all over the place. The problem is not unique to operator functions in the standard library — a significant portion of <algorithm> and <numeric> uses some operator (==, <, +, *, etc.) that may be picked up via ADL.

There is also an existing problem in that the example makes no sense anyway: the constraint in this paragraph only applies to non-members, yet ostream_iterator::operator= is a member function.

[2016-11-10, Tim Song and Jonathan agree on new wording]

The new wording still doesn't quite get it right:

"calls to non-operator, non-member functions in the standard library do not use functions from another namespace which are found through argument-dependent name lookup" can be interpreted as saying that if a user writes "std::equal(a, b, c, d)", that call will not use ADL'd "operator==" because "std::equal(a, b, c, d)" is a "call" to a "non-operator, non-member function in the standard library".

The key point here is that "in the standard library" should be modifying "calls", not "function".

Previous resolution [SUPERSEDED]:

This wording is relative to N4606.

  1. Change 16.4.6.4 [global.functions] p4:

    Unless otherwise specified, non-operator, non-member functions in the standard library shall not use functions from another namespace which are found through argument-dependent name lookup (3.4.2). [Note: The phrase "unless otherwise specified" applies to cases such as the swappable with requirements (16.4.4.3 [swappable.requirements]). The exception for overloaded operators allowsis intended to allow argument-dependent lookup in cases like that of ostream_iterator::operator= (24.6.2.2):

    Effects:

    *out_stream << value;
    if (delim != 0)
      *out_stream << delim ;
    return *this;
    

    end note]

[Issues Telecon 16-Dec-2016]

Move to Tentatively Ready

Proposed resolution:

This wording is relative to N4606.

  1. Change 16.4.6.4 [global.functions] p4:

    Unless otherwise specified, calls made by functions in the standard library to non-operator, non-member functions in the standard library shalldo not use functions from another namespace which are found through argument-dependent name lookup (3.4.2). [Note: The phrase "unless otherwise specified" applies to cases such as the swappable with requirements (16.4.4.3 [swappable.requirements]). The exception for overloaded operators allowsis intended to allow argument-dependent lookup in cases like that of ostream_iterator::operator= (24.6.2.2):

    Effects:

    *out_stream << value;
    if (delim != 0)
      *out_stream << delim ;
    return *this;
    

    end note]