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

### 3735. `views::adjacent<0>` should be prohibited

Section: 26.7.25.1 [range.adjacent.overview], 26.7.26.1 [range.adjacent.transform.overview] Status: Tentatively NAD Submitter: Hewill Kang Opened: 2022-07-13 Last modified: 2022-08-23

Priority: Not Prioritized

View all issues with Tentatively NAD status.

Discussion:

`views::adjacent` is very similar to `views::slide`, except that the window size `N` is given at compile time.

Since the case where `N` is `0` does not make sense for `slide_view`, LWG 3711 and LWG 3712 added preconditions to the constructor and removed the default constructor, respectively.

But for `views::adjacent`, we can still specify `N` to be `0`. According to the description of 26.7.25.1 [range.adjacent.overview], it will return `views::empty<tuple<>>` as in the case of `views::zip` applied to an empty pack. And for `views::adjacent_transform<0>(E, F)`, it will return `views::zip_transform(F)` and eventually return `empty_view` for some type.

This doesn't seem reasonable to me. The reason why `views::zip` can return `views::empty<tuple<>>` is that the parameter pack can indeed be empty, so this still makes some sense. However, there is no meaningful sense for the word "adjacent" when `N` is `0`.

I don't see any observable value in allowing `views::adjacent<0>`, we should disable it for consistency with `views::slide`.

[2022-08-23; Reflector poll: NAD]

`views::zip()` is exactly as meaningful as `views::adjacent<0>(E)` - it's just the edge case.

Proposed resolution:

This wording is relative to N4910.

1. Modify 26.7.25.1 [range.adjacent.overview] as indicated:

   > -2- The name `views::adjacent<N>` denotes a range adaptor object (26.7.2 [range.adaptor.object]). Given a subexpression `E` and a constant expression `N`, the expression `views::adjacent<N>(E)` is expression-equivalent to:

   > 1. (2.1) — `((void)E, auto(views::empty<tuple<>>))`I if `N` is equal to `0`, `views::adjacent<N>(E)` is ill-formed.

   > 2. (2.2) — O otherwise, `adjacent_view<views::all_t<decltype((E))>, N>(E)`.

2. Modify 26.7.26.1 [range.adjacent.transform.overview] as indicated:

   > -2- The name `views::adjacent_transform<N>` denotes a range adaptor object (26.7.2 [range.adaptor.object]). Given subexpressions `E` and `F` and a constant expression `N`:

   > 1. (2.1) — If `N` is equal to `0`, `views::adjacent_transform<N>(E, F)` is ill-formed expression-equivalent to `((void)E, views::zip_transform(F))`, except that the evaluations of `E` and `F` are indeterminately sequenced.

   > 2. (2.2) — Otherwise, the expression `views::adjacent_transform<N>(E, F)` is expression-equivalent to `adjacent_transform_view<views::all_t<decltype((E))>, decay_t<decltype((F))>, N>(E, F)`.