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)?
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>{});
}