c ++ – A cartesian product of tuples in C ++ 17

I would like to write a function that calculates a cartesian product of two tuples in C ++ 17 (the tuples can be of type std :: tuple or std :: pair, or any other type that can be used with std :: apply). The tuples can be of different types and sizes, and the result std :: tuple must contain everything std :: pairs of elements, where the first element of a couple is the first tuple, and the second the element is the second tuple. The function must be able to be used in a constexpr the context.

My approach is to use std :: apply efficiently convert a tuple into a parameter pack, then recursively apply a generic lambda to generate the result. Because a lambda can not be explicitly recursive, I pass it a reference as an additional parameter self.

#understand 
#understand 
#understand 

model
constexpr auto cartesian_product (const X & tx, const Y & ty) {
if constexpr (std :: tuple_size_v == 0) returns std :: make_tuple ();
otherwise, return std :: apply ([&](const auto & ... ys) {
returns std :: apply ([&](const auto & ... xs) {
recursive auto const = [&](
auto & self const,
const auto & arg, const auto & ... args)
{
if constexpr (sizeof ... (args) == 0)
returns std :: make_tuple (std :: make_pair (argument, ys) ...);
otherwise, return std :: tuple_cat (
std :: make_tuple (std :: make_pair (argument, ys) ...),
self (self, args ...));
};
recursive returns (recursive, xs ...);
}, tx);
}, ty);
}

// Test
constexpr auto x = std :: make_tuple (& # 39; 2);
constexpr auto y = std :: make_tuple (true, std :: optional){});
constexpr auto result = mapian_product (x, y);

static_assert (result == std :: make_tuple (
std :: make_pair ('a', true),
std :: make_pair (& # 39; a), std :: optional{}),
std :: make_pair (2, true),
std :: make_pair (2, std :: optional{})));

I would appreciate your comments or suggestions on how to simplify or improve this code.