"::std::"
everywhere rule needs tweakingSection: 16.4.2.2 [contents] Status: C++23 Submitter: Tim Song Opened: 2016-11-11 Last modified: 2023-11-22
Priority: 2
View all other issues in [contents].
View all issues with C++23 status.
Discussion:
[contents]/3 says
Whenever a name
x
defined in the standard library is mentioned, the namex
is assumed to be fully qualified as::std::x
, unless explicitly described otherwise. For example, if the Effects section for library functionF
is described as calling library functionG
, the function::std::G
is meant.
With the introduction of nested namespaces inside std
, this rule needs tweaking. For instance,
time_point_cast
's Returns clause says "time_point<Clock,
ToDuration>(duration_cast<ToDuration>(t.time_since_epoch()))
"; that reference to duration_cast
obviously means ::std::chrono::duration_cast
, not ::std::duration_cast
, which doesn't exist.
[Issues Telecon 16-Dec-2016]
Priority 2; Jonathan to provide wording
[2019 Cologne Wednesday night]
Geoffrey suggested editing 16.4.2.2 [contents]/2 to mention the case when we're defining things in a sub-namespace.
Jonathan to word this.
[2020-02-14, Prague; Walter provides wording]
[2020-10-02; Issue processing telecon: new wording from Jens]
Use "Simplified suggestion" in 13 June 2020 email from Jens.
Previous resolution [SUPERSEDED]:
This wording is relative to N4849.
Modify 16.4.2.2 [contents] as indicated:
-3-
Whenever a nameLetx
defined in the standard library is mentioned, the namex
is assumed to be fully qualified as::std::x
, unless explicitly described otherwise. For example, if the Effects: element for library functionF
is described as calling library functionG
, the function::std::G
is meant.x
be a name specified by the standard library via a declaration in namespacestd
or in a subnamespace of namespacestd
. Wheneverx
is used as an unqualified name in a further specification, it is assumed to correspond to the samex
that would be found via unqualified name lookup (6.5.3 [basic.lookup.unqual]) performed at that point of use. Similarly, wheneverx
is used as a qualified name in a further specification, it is assumed to correspond to the samex
that would be found via qualified name lookup (6.5.5 [basic.lookup.qual]) performed at that point of use. [Note: Such lookups can never fail in a well-formed program. — end note] [Example: If an Effects: element for a library functionF
specifies that library functionG
is to be used, the function::std::G
is intended. — end example]
Previous resolution [SUPERSEDED]:
This wording is relative to N4849.
Modify 16.4.2.2 [contents] as indicated:
[Drafting note: Consider adding a note clarifying that the unqualified lookup does not perform ADL. ]
-3-
Whenever a nameWhenever an unqualified namex
defined in the standard library is mentioned, the namex
is assumed to be fully qualified as::std::x
, unless explicitly described otherwise. For example, if the Effects: element for library functionF
is described as calling library functionG
, the function::std::G
is meant.x
is used in the specification of a declarationD
in clauses 16-32, its meaning is established as-if by performing unqualified name lookup (6.5.3 [basic.lookup.unqual]) in the context ofD
. Similarly, the meaning of a qualified-id is established as-if by performing qualified name lookup (6.5.5 [basic.lookup.qual]) in the context ofD
. [Example: The reference tois_array_v
in the specification ofstd::to_array
(23.3.3.6 [array.creation]) refers to::std::is_array_v
. -- end example] [Note: Operators in expressions 12.2.2.3 [over.match.oper] are not so constrained; see 16.4.6.4 [global.functions]. -- end note]
[2020-11-04; Jens provides improved wording]
[2020-11-06; Reflector discussion]
Casey suggests to insert "or Annex D" after "in clauses 16-32". This insertion has been performed during reflector discussions immediately because it seemed editorial.
[2020-11-15; Reflector poll]
Set priority status to Tentatively Ready after seven votes in favour during reflector discussions.
[2020-11-22, Tim Song reopens]
The references to get in 25.5.4.1 [range.subrange.general] and
25.7.23.2 [range.elements.view] need to be qualified as they would otherwise
refer to std::ranges::get
instead of std::get
. Additionally,
[expos.only.func] needs to clarify that the lookup there also takes
place from within namespace std
.
Previous resolution [SUPERSEDED]:
This wording is relative to N4868.
Modify 16.4.2.2 [contents] as indicated:
-3-
Whenever a nameWhenever an unqualified namex
defined in the standard library is mentioned, the namex
is assumed to be fully qualified as::std::x
, unless explicitly described otherwise. For example, if the Effects: element for library functionF
is described as calling library functionG
, the function::std::G
is meant.x
is used in the specification of a declarationD
in clauses 16-32 or Annex D, its meaning is established as-if by performing unqualified name lookup (6.5.3 [basic.lookup.unqual]) in the context ofD
. [Note ?: Argument-dependent lookup is not performed. — end note] Similarly, the meaning of a qualified-id is established as-if by performing qualified name lookup (6.5.5 [basic.lookup.qual]) in the context ofD
. [Example: The reference tois_array_v
in the specification ofstd::to_array
(23.3.3.6 [array.creation]) refers to::std::is_array_v
. — end example] [Note ?: Operators in expressions (12.2.2.3 [over.match.oper]) are not so constrained; see 16.4.6.4 [global.functions]. — end note]Remove [fs.req.namespace] in its entirety:
29.11.3.2 Namespaces and headers [fs.req.namespace]-1- Unless otherwise specified, references to entities described in subclause 31.12 [filesystems] are assumed to be qualified with::std::filesystem::
.
[2021-05-20; Jens Maurer provides an updated proposed resolution]
[2021-05-23; Daniel provides some additional tweaks to the updated proposed resolution]
[2021-05-24; Reflector poll]
Set status to Tentatively Ready after six votes in favour during reflector poll.
[2021-06-07 Approved at June 2021 virtual plenary. Status changed: Voting → WP.]
Proposed resolution:
This wording is relative to N4885.
Modify [expos.only.func] as indicated:
-2- The following are defined for exposition only to aid in the specification of the library:
namespace std { template<class T> constexpr decay_t<T> decay-copy(T&& v) noexcept(is_nothrow_convertible_v<T, decay_t<T>>) // exposition only { return std::forward<T>(v); } constexpr auto synth-three-way = []<class T, class U>(const T& t, const U& u) requires requires { { t < u } -> boolean-testable; { u < t } -> boolean-testable; } { if constexpr (three_way_comparable_with<T, U>) { return t <=> u; } else { if (t < u) return weak_ordering::less; if (u < t) return weak_ordering::greater; return weak_ordering::equivalent; } }; template<class T, class U=T> using synth-three-way-result = decltype(synth-three-way(declval<T&>(), declval<U&>())); }
Modify 16.4.2.2 [contents] as indicated:
-3-
Whenever a nameWhenever an unqualified namex
defined in the standard library is mentioned, the namex
is assumed to be fully qualified as::std::x
, unless explicitly described otherwise. For example, if the Effects: element for library functionF
is described as calling library functionG
, the function::std::G
is meant.x
is used in the specification of a declarationD
in clauses 16-32 or Annex D, its meaning is established as-if by performing unqualified name lookup (6.5.3 [basic.lookup.unqual]) in the context ofD
. [Note ?: Argument-dependent lookup is not performed. — end note] Similarly, the meaning of a qualified-id is established as-if by performing qualified name lookup (6.5.5 [basic.lookup.qual]) in the context ofD
. [Example: The reference tois_array_v
in the specification ofstd::to_array
(23.3.3.6 [array.creation]) refers to::std::is_array_v
. — end example] [Note ?: Operators in expressions (12.2.2.3 [over.match.oper]) are not so constrained; see 16.4.6.4 [global.functions]. — end note]
Modify 25.5.4.1 [range.subrange.general] as indicated:
template<class T> concept pair-like = // exposition only !is_reference_v<T> && requires(T t) { typename tuple_size<T>::type; // ensures tuple_size<T> is complete requires derived_from<tuple_size<T>, integral_constant<size_t, 2>>; typename tuple_element_t<0, remove_const_t<T>>; typename tuple_element_t<1, remove_const_t<T>>; { std::get<0>(t) } -> convertible_to<const tuple_element_t<0, T>&>; { std::get<1>(t) } -> convertible_to<const tuple_element_t<1, T>&>; };
Modify 25.7.23.2 [range.elements.view] as indicated:
template<class T, size_t N> concept has-tuple-element = // exposition only requires(T t) { typename tuple_size<T>::type; requires N <tuple_size_v<T>; typename tuple_element_t<N, T>; { std::get<N>(t) } -> convertible_to<const tuple_element_t<N, T>&>; };
Modify 25.7.23.3 [range.elements.iterator] as indicated:
-2- The member typedef-name
iterator_category
is defined if and only ifBase
modelsforward_range
. In that case,iterator_category
is defined as follows: […]
(2.1) — If
std::get<N>(*current_)
is an rvalue,iterator_category
denotesinput_iterator_tag
.[…]
static constexpr decltype(auto) get-element(const iterator_t<Base>& i); // exposition only-3- Effects: Equivalent to:
if constexpr (is_reference_v<range_reference_t<Base>>) { return std::get<N>(*i); } else { using E = remove_cv_t<tuple_element_t<N, range_reference_t<Base>>>; return static_cast<E>(std::get<N>(*i)); }
Remove [fs.req.namespace] in its entirety:
29.11.3.2 Namespaces and headers [fs.req.namespace]-1- Unless otherwise specified, references to entities described in subclause 31.12 [filesystems] are assumed to be qualified with::std::filesystem::
.