У меня есть следующий код, который объединяет два вектора произвольных типов в комбинаторный, то есть std::vector<std::tuple<A, B>>
.
template<class A, class B>
std::vector<std::tuple<A, B>> combine(const std::vector<A>& a, const std::vector<B>& b) {
const auto combine_parts_ = [](const A& x, const B& y) {
auto result = std::tuple_cat(std::make_tuple(x), std::make_tuple(y));
return result;
};
std::vector<std::tuple<A, B>> results;
for (const auto& x : a) {
for (const auto& y : b) {
results.push_back(combine_parts_(x, y));
}
}
return results;
}
Однако мне неясно, как расширить это на произвольное количество типов / векторов. Меня не волнуют дубликаты типов; на самом деле может быть два или более наборов одного и того же типа. Это нормально.
Некоторые примеры использования, например:
const auto combinations = combine(
std::vector<int>({1,2,3})
, std::vector<int>({1,2,3})
);
const auto combinations2 = combine(
std::vector<int>({1,2,3})
, std::vector<int>({1,2,3})
, std::vector<bool>({true,false})
);
const auto combinations3 = combine(
std::vector<int>({1,2,3})
, std::vector<int>({1,2,3})
, std::vector<bool>({true,false})
, std::vector<char>({'a','b','c','d','e'})
);
В основном, я хочу избежать уродливого цикла for. В то же время я хочу объединить некоторые комбинаторные варианты использования модульного тестирования, чтобы работать с результирующим std::tuple<...>
в качестве контрольного примера.
Заметьте, я не говорю здесь о перестановках однородного множества. Это было путаницей из предыдущих вопросов.
Я думаю, что это может иметь какое-то отношение к шаблонам, variadics, std::tuple_cat
, где-то по пути, но я не знаю.
Мысли? Предложения?