Title
Misleading note about calls to customization points
Status
c++23
Section
[namespace.std]
Submitter
Michael Park

Created on 2020-05-08.00:00:00 last changed 5 months ago

Messages

Date: 2023-02-13.11:31:32

Proposed resolution:

This wording is relative to n4928.

  1. Modify [namespace.std] as indicated:

    [Drafting note: This should also remove the only index entry for "customization point". ]

    -7- Other than in namespace std or in a namespace within namespace std, a program may provide an overload for any library function template designated as a customization point, provided that (a) the overload's declaration depends on at least one user-defined type and (b) the overload meets the standard library requirements for the customization point. 163

    [Note 3: This permits a (qualified or unqualified) call to the customization point to invoke the most appropriate overload for the given arguments. — end note]

    163) 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 can 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.

  2. Modify [utility.swap] as indicated:

    
    template<class T>
      constexpr void swap(T& a, T& b) noexcept(see below);
    

    -1- Constraints: is_move_constructible_v<T> is true and is_move_assignable_v<T> is true.

    -2- Preconditions: Type T meets the Cpp17MoveConstructible (Table 32) and Cpp17MoveAssignable (Table 34) requirements.

    -3- Effects: Exchanges values stored in two locations.

    -4- Remarks: This function is a designated customization point ([namespace.std]). The exception specification is equivalent to:

    
    is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T>
    

  3. Modify [iterator.range] as indicated:

    -1- In addition to being available via inclusion of the <iterator> header, the function templates in [iterator.range] are available when any of the following headers are included: <array> ([array.syn]), <deque> ([deque.syn]), <forward_list> ([forward.list.syn]), <list> ([list.syn]), <map> ([associative.map.syn]), <regex> ([re.syn]), <set> ([associative.set.syn]), <span> ([span.syn]), <string> ([string.syn]), <string_view> ([string.view.syn]), <unordered_map> ([unord.map.syn]), <unordered_set> ([unord.set.syn]), and <vector> ([vector.syn]). Each of these templates is a designated customization point ([namespace.std]).

Date: 2023-02-13.00:00:00

[ 2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Immediate → WP. ]

Date: 2023-02-10.00:46:49

[ Issaquah 2023-02-09; LWG ]

Move to Immediate for C++23

Date: 2023-02-10.00:46:49

[ Issaquah 2023-02-09; Jonathan provides improved wording ]

The normative part of [namespace.std] paragraph 7 (i.e. not the note and the footnote) does not actually do anything except tell users they're not allowed to use the names begin, size etc. unless they conform to the provisions of paragraph 7. This means a program that contains the following declaration might have undefined behaviour:

namespace user { int data(int, int); }
This is not OK! It's not even clear what "the requirements for the customization point" are, if users wanted to meet them. It's not even clear what "provide an overload" means.

In particular, paragraph 7 does not give permission for the designated customization points to actually use such overloads. Just by forbidding users from using data for their own functions isn't sufficient to allow the library to use ADL to call data, and it's unclear why we'd want that anyway (what problem with std::data are we trying to solve that way?). As shown in LWG 3442, if std::data became a customization point that would be a backwards-incompatible change, and create a portability problem if some implementations did that and others didn't.

So the non-normative note and footnote make claims that do not follow from the normative wording, and should be removed.

The only one of the designated customization points that is actually looked up using ADL is std::swap, but how that works is fully specified by [contents] and [swappable.requirements]. The additional specification that it's a designated customization point serves no benefit. In particular, the permission that the note and footnote claim exists is not needed. We specify precisely how swap calls are performed. We don't even need to say that user overloads of swap in their own namespaces must meet the library requirements, because the "swappable with" and Cpp17Swappable requirements state the required semantics, and functions that use swap have preconditions that the types are swappable. So we correctly impose preconditions in the places that actually call swap, and don't need to globally make it undefined for any function called swap to not meet the requirements, even if that function is never found by ADL by the library (e.g. because it's in a namespace that is never an associated namespace of any types used with library components that require swappable types).

Paragraph 7 and its accompanying notes should go.

Date: 2020-10-15.00:00:00

[ 2020-10-02; status to Open ]

Previous resolution [SUPERSEDED]:

This wording is relative to N4861.

  1. Modify [namespace.std] as indicated:

    -7- Other than in namespace std or in a namespace within namespace std, a program may provide an overload for any library function template designated as a customization point, provided that (a) the overload's declaration depends on at least one user-defined type and (b) the overload meets the standard library requirements for the customization point. (footnote 173) [Note: This permits a (qualified or unqualified) call to the customization point to invoke the most appropriate overload for the given arguments. — end note]

Date: 2020-09-15.00:00:00

[ 2020-09-11; discussed during telecon ]

The note is simply bogus, not backed up by anything normative. The normative part of the paragraph is an unacceptable landgrab on those identifiers. We have no right telling users they can't use the names data and size unless they do exactly what we say std::data and std::size do. The library only ever uses swap unqualified, so the effect of declaring the others as designated customization points is unclear.

The rule only needs to apply to such overloads when actually found by overload resolution in a context that expects the semantics of the customization point.

Frank: do we need to designate operator<< as a customization point? Users overload that in their own namespaces all the time.

Walter: This clearly needs a paper.

Date: 2020-07-15.00:00:00

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

Related to 3442.

Date: 2020-05-08.00:00:00

P0551 (Thou Shalt Not Specialize std Function Templates!) added a clause in [namespace.std]/7:

Other than in namespace std or in a namespace within namespace std, a program may provide an overload for any library function template designated as a customization point, provided that (a) the overload's declaration depends on at least one user-defined type and (b) the overload meets the standard library requirements for the customization point. (footnote 174) [Note: This permits a (qualified or unqualified) call to the customization point to invoke the most appropriate overload for the given arguments. — end note]

Given that std::swap is a designated customization point, the note seems to suggest the following:

namespace N {
  struct X {};
  void swap(X&, X&) {}
}

N::X a, b;
std::swap(a, b); // qualified call to customization point finds N::swap?

This is not what happens, as the call to std::swap does not find N::swap.

History
Date User Action Args
2023-11-22 15:47:43adminsetstatus: wp -> c++23
2023-02-13 11:31:32adminsetmessages: + msg13377
2023-02-13 11:31:32adminsetstatus: immediate -> wp
2023-02-10 00:54:15adminsetstatus: open -> immediate
2023-02-10 00:46:49adminsetmessages: + msg13323
2023-02-10 00:11:39adminsetmessages: + msg13320
2020-10-02 18:55:49adminsetmessages: + msg11500
2020-10-02 18:55:49adminsetstatus: new -> open
2020-09-12 11:45:45adminsetmessages: + msg11477
2020-07-17 22:37:26adminsetmessages: + msg11377
2020-05-09 19:58:13adminsetmessages: + msg11281
2020-05-08 00:00:00admincreate