Search code examples
c++c++23

views::cartesian_product - how to do same vector N times?


This code works

#include <iostream>
#include <ranges>
#include <vector>
 
int main()
{
    const auto y = std::vector{1, 2, 3};    

    for (int i{1}; auto const &[a, b, c] : std::views::cartesian_product(y, y, y))
        std::cout << "(" << a << ' ' << b << ' ' << c << ')' << (i++ % 3 ? " " : "\n");
    
}

And produces the output

$ g++-12-master --std=c++23 cartesian.cpp -o cartesian.exe && ./cartesian.exe
(1 1 1) (1 1 2) (1 1 3)
(1 2 1) (1 2 2) (1 2 3)
(1 3 1) (1 3 2) (1 3 3)
(2 1 1) (2 1 2) (2 1 3)
(2 2 1) (2 2 2) (2 2 3)
(2 3 1) (2 3 2) (2 3 3)
(3 1 1) (3 1 2) (3 1 3)
(3 2 1) (3 2 2) (3 2 3)
(3 3 1) (3 3 2) (3 3 3)

Is there syntax where I can pass in the const auto y = std::vector{1, 2, 3}; once and specify an integer (in this case 3)?


Solution

  • Assuming N can be a template parameter, you can populate a call to std::views::cartesian_product in a pack expansion:

    template <size_t N>
    auto product(auto&& v)
    {
        return [&v]<size_t... Is>(std::index_sequence<Is...>)
            { return std::views::cartesian_product((Is, v)...); }
            (std::make_index_sequence<N>{});
    }
    

    See it live