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

### 2818. `"::std::"` everywhere rule needs tweaking

Section: 16.4.2.2 [contents] Status: WP Submitter: Tim Song Opened: 2016-11-11 Last modified: 2021-06-07

Priority: 2

View all other issues in [contents].

View all issues with WP status.

Discussion:

[contents]/3 says

> Whenever a name `x` defined in the standard library is mentioned, the name `x` is assumed to be fully qualified as `::std::x`, unless explicitly described otherwise. For example, if the Effects section for library function `F` is described as calling library function `G`, 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.

> 1. Modify 16.4.2.2 [contents] as indicated:

>    > -3- Whenever a name `x` defined in the standard library is mentioned, the name `x` is assumed to be fully qualified as `::std::x`, unless explicitly described otherwise. For example, if the Effects: element for library function `F` is described as calling library function `G`, the function `::std::G` is meant.Let `x` be a name specified by the standard library via a declaration in namespace `std` or in a subnamespace of namespace `std`. Whenever `x` is used as an unqualified name in a further specification, it is assumed to correspond to the same `x` that would be found via unqualified name lookup (6.5.3 [basic.lookup.unqual]) performed at that point of use. Similarly, whenever `x` is used as a qualified name in a further specification, it is assumed to correspond to the same `x` 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 function `F` specifies that library function `G` is to be used, the function `::std::G` is intended. — end example]

Previous resolution [SUPERSEDED]:

> This wording is relative to N4849.

> 1. 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 name `x` defined in the standard library is mentioned, the name `x` is assumed to be fully qualified as `::std::x`, unless explicitly described otherwise. For example, if the Effects: element for library function `F` is described as calling library function `G`, the function `::std::G` is meant. Whenever an unqualified name `x` is used in the specification of a declaration `D` in clauses 16-32, its meaning is established as-if by performing unqualified name lookup (6.5.3 [basic.lookup.unqual]) in the context of `D`. 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 of `D`. [Example: The reference to `is_array_v` in the specification of `std::to_array` (22.3.7.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 24.5.4.1 [range.subrange.general] and 24.7.18.2 [range.elements.view] need to be qualified as they would otherwise refer to `std::ranges::get` instead of `std::get`. Additionally, 16.3.3.2 [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.

> 1. Modify 16.4.2.2 [contents] as indicated:

>    > -3- Whenever a name `x` defined in the standard library is mentioned, the name `x` is assumed to be fully qualified as `::std::x`, unless explicitly described otherwise. For example, if the Effects: element for library function `F` is described as calling library function `G`, the function `::std::G` is meant. Whenever an unqualified name `x` is used in the specification of a declaration `D` 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 of `D`. [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 of `D`. [Example: The reference to `is_array_v` in the specification of `std::to_array` (22.3.7.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]

> 2. 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 29.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.

1. Modify 16.3.3.2 [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&>()));
   > >     }

2. Modify 16.4.2.2 [contents] as indicated:

   > -3- Whenever a name `x` defined in the standard library is mentioned, the name `x` is assumed to be fully qualified as `::std::x`, unless explicitly described otherwise. For example, if the Effects: element for library function `F` is described as calling library function `G`, the function `::std::G` is meant. Whenever an unqualified name `x` is used in the specification of a declaration `D` 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 of `D`. [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 of `D`. [Example: The reference to `is_array_v` in the specification of `std::to_array` (22.3.7.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]

3. Modify 24.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>&>;
   >         };

4. Modify 24.7.18.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>&>;
   >         };

5. Modify 24.7.18.3 [range.elements.iterator] as indicated:

   > -2- The member typedef-name `iterator_category` is defined if and only if `Base` models `forward_range`. In that case, `iterator_category` is defined as follows: […]

   > 1. (2.1) — If `std::get<N>(*current_)` is an rvalue, `iterator_category` denotes `input_iterator_tag`.

   > 2. […]

   >     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));
   > > >     }

6. 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 29.12 [filesystems] are assumed to be qualified with `::std::filesystem::`.