This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Resolved status.

3442. Unsatisfiable suggested implementation of customization points

Section: 16.4.5.2.1 [namespace.std] Status: Resolved Submitter: Michael Park Opened: 2020-05-08 Last modified: 2023-03-22

Priority: 1

View other active issues in [namespace.std].

View all other issues in [namespace.std].

View all issues with Resolved status.

Discussion:

Footnote 173 under [namespace.std]/7 reads (emphasis mine):

Any library customization point must be prepared to work adequately with any user-defined overload that meets the minimum requirements of this document. Therefore an implementation may elect, under the as-if rule (6.9.1 [intro.execution]), to provide any customization point in the form of an instantiated function object (22.10 [function.objects]) even though the customization point's specification is in the form of a function template. The template parameters of each such function object and the function parameters and return type of the object's operator() must match those of the corresponding customization point's specification.

This implementation suggestion doesn't seem to be satisfiable with the as-if rule.

  1. In order to maintain as-if rule for qualified calls to std::swap, std::swap cannot perform ADL look-up like std::ranges::swap does.

  2. But then we cannot maintain as-if rule for two-step calls to std::swap, since ADL is turned off when function objects are involved.

    #include <iostream>
    
    namespace S {
    #ifdef CPO
      static constexpr auto swap = [](auto&, auto&) { std::cout << "std"; };
    #else
      template<typename T> swap(T&, T&) { std::cout << "std"; }
    #endif
    }
    
    namespace N {
      struct X {};
      void swap(X&, X&) { std::cout << "mine"; }
    }
    
    int main() {
      N::X a, b;
      S::swap(a, b);  // (1) prints std in both cases
      using S::swap;
      swap(a, b);     // (2) prints std with -DCPO, and mine without.
    }
    
  3. We can try to satisfy the as-if rule for (2) by having std::swap perform ADL like std::ranges::swap, but then that would break (1) since qualified calls to std::swap would also ADL when it did not do so before.

[2020-07-17; Priority set to 1 in telecon]

Related to 3441(i).

[2020-10-02; status to Open]

[Issaquah 2023-02-09; Jonathan adds note]

This would be resolved by the new proposed resolution of LWG 3441(i).

[2023-03-22 LWG 3441 was approved in Issaquah. Status changed: Open → Resolved.]

Proposed resolution:

This wording is relative to N4861.

  1. Modify 16.4.5.2.1 [namespace.std], footnote 173, as indicated:

    footnote 173) Any library customization point must be prepared to work adequately with any user-defined overload that meets the minimum requirements of this document. Therefore an implementation may elect, under the as-if rule (6.9.1 [intro.execution]), to provide any customization point in the form of an instantiated function object (22.10 [function.objects]) even though the customization point's specification is in the form of a function template. The template parameters of each such function object and the function parameters and return type of the object's operator() must match those of the corresponding customization point's specification.