Title
Unsatisfiable suggested implementation of customization points
Status
new
Section
[namespace.std]
Submitter
Michael Park

Created on 2020-05-08.00:00:00 last changed 2 weeks ago

Messages

Date: 2020-05-09.20:16:07

Proposed resolution:

This wording is relative to N4861.

  1. Modify [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 ([intro.execution]), to provide any customization point in the form of an instantiated function object ([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.

Date: 2020-05-08.00:00:00

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 ([intro.execution]), to provide any customization point in the form of an instantiated function object ([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.

History
Date User Action Args
2020-05-09 20:16:07adminsetmessages: + msg11283
2020-05-08 00:00:00admincreate