Section hub

std::ranges::views::cartesian_product, std::ranges::cartesian_product_view

  1. cartesian_product_view is a range adaptor that takes n views, where n > 0, and produces a view of tuples calculated by the n-ary cartesian product of the provided ranges. The size of produced view is a multiple of sizes of provided ranges, while each element is a tuple (of references) of the size n.

# Declarations

template< ranges::input_range First, ranges::forward_range... Vs >
requires (ranges::view<First> && ... && ranges::view<Vs>)
class cartesian_product_view
: public ranges::view_interface<cartesian_product_view<First, Vs...>>

(since C++23)

namespace views {
inline constexpr /*unspecified*/ cartesian_product = /*unspecified*/;
}

(since C++23)

Call signature
template< ranges::viewable_range... Rs >
requires /* see below */
constexpr ranges::view auto cartesian_product( Rs&&... rs );

(since C++23)

Helper concepts
template< bool Const, class First, class... Vs >
concept /*cartesian-product-is-random-access*/ =
(ranges::random_access_range</*maybe-const*/<Const, First>> && ... &&
(ranges::random_access_range</*maybe-const*/<Const, Vs>> &&
ranges::sized_range</*maybe-const*/<Const, Vs>>));

(exposition only*)

template< class R >
concept /*cartesian-product-common-arg*/ =
ranges::common_range<R> ||
(ranges::sized_range<R> && ranges::random_access_range<R>);

(exposition only*)

template< bool Const, class First, class... Vs >
concept /*cartesian-product-is-bidirectional*/ =
(ranges::bidirectional_range</*maybe-const*/<Const, First>> && ... &&
(ranges::bidirectional_range</*maybe-const*/<Const, Vs>> &&
/*cartesian-product-common-arg*/</*maybe-const*/<Const, Vs>>));

(exposition only*)

template< class First, class... Vs >
concept /*cartesian-product-is-common*/ =
/*cartesian-product-common-arg*/<First>;

(exposition only*)

template< class... Vs >
concept /*cartesian-product-is-sized*/ =
(ranges::sized_range<Vs> && ...);

(exposition only*)

template< bool Const, template<class> class FirstSent, class First, class... Vs >
concept /*cartesian-is-sized-sentinel*/ =
(std::sized_sentinel_for<FirstSent</*maybe-const*/<Const, First>>,
ranges::iterator_t</*maybe-const*/<Const, First>>> && ... &&
(ranges::sized_range</*maybe-const*/<Const, Vs>> &&
std::sized_sentinel_for<ranges::iterator_t<
/*maybe-const*/<Const, Vs>>,
ranges::iterator_t</*maybe-const*/<Const, Vs>>>));

(exposition only*)

Helper function templates
template< /*cartesian-product-common-arg*/ R >
constexpr auto /*cartesian-common-arg-end*/( R& r )
{
if constexpr (ranges::common_range<R>)
return ranges::end(r);
else
return ranges::begin(r) + ranges::distance(r);
}

(exposition only*)

# Notes

Feature-test macro Value Std Feature __cpp_lib_ranges_cartesian_product 202207L (C++23) std::ranges::cartesian_product_view

# Example

#include <array>
#include <iostream>
#include <list>
#include <ranges>
#include <string>
#include <vector>
 
void print(std::tuple<char const&, int const&, std::string const&> t, int pos)
{
    const auto& [a, b, c] = t;
    std::cout << '(' << a << ' ' << b << ' ' << c << ')' << (pos % 4 ? " " : "\n");
}
 
int main()
{
    const auto x = std::array{'A', 'B'};
    const auto y = std::vector{1, 2, 3};
    const auto z = std::list<std::string>{"α", "β", "γ", "δ"};
 
    for (int i{1}; auto const& tuple : std::views::cartesian_product(x, y, z))
        print(tuple, i++);
}

# See also

This hub groups the ranges library by user task rather than by raw reference tree shape. View types and adaptor objects are presented as the same conceptual item.

Core adapters

Start here for the adapters most people reach for first when building pipelines.

Utility views

These adapt shape, ownership, or projection rather than representing the “headline” pipeline steps.

New in C++23 / C++26

Newer adapters, kept as a compact scan list with only standard badges.

All entities by category

A lighter-weight index of the full ranges surface, grouped by conceptual task instead of raw page-tree names.

74 entities