这个问题是kind of asked before,但我不确定是否真的提供了令人满意的答案。对我来说,我对std::vector
std::string
本身,而不是std::tuple
感兴趣。
例如,如果我有std::vector<A>
,std::vector<B>
和std::vector<C>
,那么我希望std::vector<std::tuple<A, B, C>>
。或者,即使std::set<std::tuple<A, B, C>>
,如果那更合适。
现在,我可以对嵌套的for
循环进行编码,但是,如果可能的话,我想通过函数,模板函数来实现这一点,然后我认为variadic是完成任务所必需的。
无法保证A
,B
或C
彼此之间有任何关系,更不用说转换为std::string
了,正如一对夫妇所提议的那样回应。
我想说可以有一个可变的解决方案,但我不确定如何撰写std::vector<T>
或std::vector<T>::value_type
定义。
答案 0 :(得分:3)
如果要计算异构向量的笛卡尔积,可以执行以下操作:
template <std::size_t N>
bool increase(const std::array<std::size_t, N>& sizes, std::array<std::size_t, N>& it)
{
for (std::size_t i = 0; i != N; ++i) {
const std::size_t index = N - 1 - i;
++it[index];
if (it[index] >= sizes[index]) {
it[index] = 0;
} else {
return true;
}
}
return false;
}
template <typename F, std::size_t ... Is, std::size_t N, typename Tuple>
void apply_impl(F&& f,
std::index_sequence<Is...>,
const std::array<std::size_t, N>& it,
const Tuple& tuple)
{
f(std::get<Is>(tuple)[it[Is]]...);
}
template <typename F, typename ... Ts>
void iterate(F&& f, const std::vector<Ts>&... vs)
{
constexpr std::size_t N = sizeof...(Ts);
std::array<std::size_t, N> sizes{{vs.size()...}};
std::array<std::size_t, N> it{{(vs.size(), 0u)...}};
do {
apply_impl(f, std::index_sequence_for<Ts...>(), it, std::tie(vs...));
} while (increase(sizes, it));
}