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

4613. The const overloads of elements_view's begin()/end() are underconstrained

Section: 25.7.23.2 [range.elements.view] Status: New Submitter: S. B. Tam Opened: 2026-08-15 Last modified: 2026-08-15

Priority: Not Prioritized

View all other issues in [range.elements.view].

View all issues with New status.

Discussion:

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?

Proposed resolution: