C++ named requirements: RangeAdaptorClosureObject (since C++20)

< cpp‎ | named req
C++ named requirements
Type properties
Container Elements

Stream I/O
Random Numbers


Range adaptor closure objects are FunctionObjects that take one viewable_range (until C++23) range (since C++23) as its only argument and returns a view (until C++23). They are callable via the pipe operator: if C is a range adaptor closure object and R is a viewable_range (until C++23) range (since C++23), these two expressions are equivalent (both well-formed or ill-formed):

R | C

This call forwards the bound arguments (if any) to the associated range adaptor object. The bound arguments (if any) are identically treated as lvalue or rvalue and cv-qualified to C.

Two range adaptor closure objects can be chained by operator| to produce another range adaptor closure object: if C and D are range adaptor closure objects, then C | D is also a range adaptor closure object if it is valid.

The bound arguments of C | D is determined as follows:

  • there is a subobject in the result object of the same type (cv-qualification discarded) for every subobject in both operands that is a bound argument,
  • such a bound argument is direct-non-list-initialized with the source subobject in its containing operand, where the source is identically treated as lvalue or rvalue and cv-qualified to the operand,
  • the result is valid if and only if the initialization of all bound arguments are valid.

The effect and validity of the operator() of the result is determined as follows: given a viewable_range (until C++23) range (since C++23) R, these two expressions are equivalent (both well-formed or ill-formed):

R | C | D // (R | C) | D
R | (C | D)

Notes: operator() is unsupported for volatile-qualified or const-volatile-qualified version of range adaptor object closure types.

Objects whose type is the same as one of the following objects (ignoring cv-qualification) are range adaptor closure objects:

  • unary range adaptor objects,
  • objects of user-defined types other than unary range adaptor objects who meet the requirements of implementing a range adaptor closure object,
(since C++23)
  • the results of binding trailing arguments by range adaptor objects, and
  • the results of chaining two range adaptor closure objects by operator|.

Let t be the object of type T, then t is a range adaptor closure object if all the requirements are met:

  • t is a unary function object that takes one range argument.
  • T has exactly one public base class ranges::range_adaptor_closure<T>, and T has no base classes of type ranges::range_adaptor_closure<U> for any other type U.
  • T does not satisfy range.
(since C++23)