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

### 3183. Normative permission to specialize Ranges variable templates

Section: 25.3.4.8 [iterator.concept.sizedsentinel] Status: C++20 Submitter: Casey Carter Opened: 2019-01-14 Last modified: 2021-02-25

Priority: 0

View all issues with C++20 status.

Discussion:

P0896R4 "The One Ranges Proposal" added boolean variable templates `std::disable_sized_sentinel` and `std::ranges::disable_sized_range` which users are intended to specialize to `false` for program-defined `Iterator`-`Sentinel` pairs / `Range` types which meet the syntax but do not model the semantics of the `SizedSentinel` / `SizedRange` concepts, respectively. Specializing these traits allows the use of such types with the library which would otherwise treat them as if they model `SizedSentinel` / `SizedRange`. The wording in P0896R4 failed, however, to provide normative permission to specialize these variable templates as is required by 16.4.5.2.1 [namespace.std] after the application of P0551R3.

Furthermore, 16.4.5.2.1 [namespace.std] notably does not require that program-defined specializations of standard library variable templates meet the requirements on the primary template (as is the case for class templates) or indeed any requirements. P0896R4 also added the `enable_view` variable template which is used to explicitly opt in or out of the `View` concept 26.4.4 [range.view] when the default chosen by the heuristic is incorrect. P0896R4 did include normative permission to specialize `enable_view`, but the wording does not place sufficient requirements on such user specializations so as to make them usable by the `View` concept definition. Specializations must be required to be usable as constant expressions of type `bool` to avoid hard errors in the concept.

[2019-02-03 Priority to 0 and Status to Tentatively Ready after five positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4791.

> [Drafting Note: This wording uses the recently-defined core language term "usable in constant expressions" from 7.7 [expr.const] paragraph 3 which may be unfamiliar to reviewers.]

1. Change 25.3.4.8 [iterator.concept.sizedsentinel] as follows:

   > […]

   > (2.2) — If `−N` is representable by `iter_difference_t<I>`, then `i - s` is well-defined and equals `−N`.

   > -?- Pursuant to 16.4.5.2.1 [namespace.std], users may specialize `disable_sized_sentinel` for cv-unqualified non-array object types `S` and `I` at least one of which is a program-defined type. Such specializations shall be usable in constant expressions (7.7 [expr.const]) and have type `const bool`.

   > 3 [Note: `disable_sized_sentinel` allows use of sentinels and iterators with the library that satisfy but do not in fact model `SizedSentinel`.—end note]

   > […]

2. Add an index entry for `disable_sized_sentinel` that points to [iterator.concepts.sizedsentinel].

3. Change 26.4.3 [range.sized] as follows:

   > […]

   > 3 [Note: The complexity requirement for the evaluation of `ranges::size` is non-amortized, unlike the case for the complexity of the evaluations of `ranges::begin` and `ranges::end` in the `Range` concept.—end note]

   > -?- Pursuant to 16.4.5.2.1 [namespace.std], users may specialize `disable_sized_range` for cv-unqualified program-defined types. Such specializations shall be usable in constant expressions (7.7 [expr.const]) and have type `const bool`.

   > 4 [Note: `disable_sized_range` allows use of range types with the library that satisfy but do not in fact model `SizedRange`.—end note]

4. Add an index entry for `disable_sized_range` that points to 26.4.3 [range.sized].

5. Change 26.4.4 [range.view] as follows:

   > […]

   > 5 Pursuant to 16.4.5.2.1 [namespace.std], users may specialize `enable_view` to `true` for cv-unqualified program-defined types which model `View`, and `false` for types which do not. Such specializations shall be usable in constant expressions (7.7 [expr.const]) and have type `const bool`.