std::ranges::views::common, std::ranges::common_view

< cpp‎ | ranges
Defined in header <ranges>
template< ranges::view V >

    requires (!ranges::common_range<V> && std::copyable<ranges::iterator_t<V>>)

class common_view : public ranges::view_interface<common_view<V>>
(1) (since C++20)
namespace views {

    inline constexpr /*unspecified*/ common = /*unspecified*/;

(2) (since C++20)
1) Converts a given view with different types for iterator/sentinel pair into a view with the same type for iterator/sentinel.
2) Let E be a subexpression. Then the expression views​::​common(E) is expression-equivalent to:
  • views​::​all(E), if it is a well-formed expression and decltype((E)) models common_range;
  • common_­view{E} otherwise.


[edit] Expression-equivalent

Expression e is expression-equivalent to expression f, if e and f have the same effects, either are both potentially-throwing or are both not potentially-throwing (i.e. noexcept(e) == noexcept(f)), and either are both constant subexpressions or are both not constant subexpressions.

[edit] Data members


V base_ = V(); /* exposition-only */

the underlying view.

[edit] Member functions

constructs a common_view
(public member function) [edit]
returns a copy of the underlying (adapted) view
(public member function) [edit]
returns an iterator to the beginning
(public member function) [edit]
returns an iterator to the end
(public member function) [edit]
returns the number of elements. Provided only if the underlying (adapted) range satisfies sized_range
(public member function) [edit]

[edit] Deduction guides

[edit] Helper templates

template<class T>

inline constexpr bool enable_borrowed_range<std::ranges::common_view<T>> =

(since C++20)

This specialization of std::ranges::enable_borrowed_range makes common_view satisfy borrowed_range when the underlying view satisfies it.

[edit] Notes

common_­view can be useful for working with legacy algorithms that expect common_range iterators (i.e. the types of iterators that represent the begin and the end of a sequence to be the same).

[edit] Example

#include <iostream>
#include <numeric>
#include <ranges>
#include <string>
void print_sum(auto&& v) {
    auto cv { v | std::views::common };  // turns into a "common-range"
    using T = decltype(*cv.begin());  // needed to get initial value of the sum
    for (bool first{true}; auto const& e : cv)  // print range
        std::cout << (first ? first = false, "" : " + ") << e;
    std::cout << " = " << std::accumulate(cv.begin(), cv.end(), T{}) << '\n';
int main() {
    const auto v1 = {1, 2, 3, 4, 5};
    auto take3 = v1 | std::views::reverse | std::views::take(3);
    print_sum(take3); // 5 + 4 + 3
    using namespace std::literals;
    const auto v2 = { "[alpha]"s, "[beta]"s, "[gamma]"s };


1 + 2 + 3 + 4 + 5 = 15
5 + 4 + 3 = 12
[alpha] + [beta] + [gamma] = [alpha][beta][gamma]

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG 3494 C++20 common_view was never a borrowed_range it is a borrowed_range if its underlying view is

[edit] See also

a view that includes all elements of a range
(alias template) (range adaptor object) [edit]
specifies that a range has identical iterator and sentinel types
(concept) [edit]