Title
The `const` overloads of `elements_view`'s `begin()`/`end()` are underconstrained
Status
new
Section
[range.elements.view]
Submitter
S. B. Tam

Created on 2026-08-15.00:00:00 last changed 1 week ago

Messages

Date: 2026-08-15.00:00:00

The `const` overloads of `elements_view`'s `begin()` and `end()` only require `const V` to satisfy `range`, and do not check if its value type is tuple-like (or if it has a value type at all). In the unusual case where `V` and `const V` have different value types, evaluating range<const elements_view<V, N>> will fail with a hard error, because the function body of the `const` `begin()` overload gets instantiated, which instantiates `elements_view`'s iterator with an unexpected value type.

Example:

#include <ranges>
#include <tuple>

struct Rng 
{
  std::tuple<int>* begin();
  std::tuple<int>* end();

  int* begin() const;
  int* end() const;
};

auto r = Rng{} | std::views::elements<0>;
using T = decltype(r);
static_assert(!std::ranges::range<const T>); // hard error

Other range adaptors in the standard library tend to have properly constrained `begin()`/`end()` overloads, so that the `range` check is SFINAE-friendly. Should `elements_view` follow suit?

History
Date User Action Args
2026-08-15 00:00:00admincreate