Proposed resolution:
This wording is relative to N4910.
Modify [contents] as indicated:
[…]
-3- Whenever an unqualified name other than swap is used in the specification of a declaration D in Clause [support] through Clause [thread] or Annex [depr], its meaning is established as-if by performing unqualified name lookup ([basic.lookup.unqual]) in the context of D.
[Note 1: Argument-dependent lookup is not performed. — end note]
Similarly, the meaning of a qualified-id is established as-if by performing qualified name lookup ([basic.lookup.qual]) in the context of D.
[Example 1: The reference to is_array_v in the specification of std::to_array ([array.creation]) refers to ::std::is_array_v. — end example]
[Note 2: Operators in expressions ([over.match.oper]) are not so constrained; see [global.functions]. — end note] The meaning of the unqualified name swap is established in an overload resolution context for swappable values ([swappable.requirements]).
Certain entities in the standard library are specified to select tuple-like get function templates. An implementation shall behave as if every tuple-like get function template is found in the definition of such an entity. Furthermore, an implementation shall ensure that no get function template that is not tuple-like is found in the definition of such an entity.
Add to the end of [pair.astuple], [tuple.elem], [array.tuple], and [range.subrange.access] as indicated:
The get function templates specified in this section are tuple-like ([contents]).
Modify [tuple.apply] as indicated:
template<class F, class Tuple> constexpr decltype(auto) apply(F&& f, Tuple&& t);-1- Effects: Given the exposition-only function:
namespace std { template<class F, class Tuple, size_t... I> constexpr decltype(auto) apply-impl(F&& f, Tuple&& t, index_sequence<I...>) { // exposition only return INVOKE(std::forward<F>(f), get<I>(std::forward<Tuple>(t))...); // see [func.require] } }
Equivalent to:
return apply-impl(std::forward<F>(f), std::forward<Tuple>(t), make_index_sequence<tuple_size_v<remove_reference_t<Tuple>>>{});-?- Remarks: apply-impl selects tuple-like get function templates.
template<class T, class Tuple> constexpr T make_from_tuple(Tuple&& t);-2- Mandates: If tuple_size_v<remove_reference_t<Tuple>> is 1, then reference_constructs_from_temporary_v<T, decltype(get<0>(declval<Tuple>()))> is false.
-3- Effects: Given the exposition-only function:
namespace std { template<class T, class Tuple, size_t... I> requires is_constructible_v<T, decltype(get<I>(declval<Tuple>()))...> constexpr T make-from-tuple-impl(Tuple&& t, index_sequence<I...>) { // exposition only return T(get<I>(std::forward<Tuple>(t))...); } }Equivalent to:
return make-from-tuple-impl<T>( std::forward<Tuple>(t), make_index_sequence<tuple_size_v<remove_reference_t<Tuple>>>{});[…]
-?- Remarks: make-from-tuple-impl selects tuple-like get function templates.
Add at the end of [range.subrange.general] (after the synopsis) as indicated:
[Drafting note: Although IIUC pair-like is not needed to handle array and subrange.]
[…]
-?- Remarks: pair-like selects tuple-like get function templates.
Add after the synopsis of [range.elements.view] as indicated:
[…]
-?- Remarks: has-tuple-element selects tuple-like get function templates.
[…]