如何使用笛卡尔积将向量元组转换为元组的向量
How to convert a tuple of vectors into a vector of tuples using the Cartesian product?
为了对带有std::tuple
构造函数的类进行单元测试,我想生成一个特殊情况的示例以及构造函数参数的随机值。假设我有std::vector<T1>
到std::vector<Tn>
的std::tuple
,(其中每个Ti
都是不同的)我如何将其转换为所有std::tuple<T1, ..., Tn>
组合的完整笛卡尔积的std::vector
?
具体来说,我想有一个可变函数模板,看起来像这样:
template<typename... Args>
std::vector<std::tuple<Args...> cartesian_product(std::vector<Args>...)
{
// template magic or fat mulitple loops?
}
和可以这样使用:
// some type to be tested
class MyType
{
MyType(std::tuple<int, bool, std::string>);
// bla
};
// test values for each constructor argument
std::tuple< std::vector<int>, std::vector<bool>, std::vector<std::string> > input {
{ 1, 2, 3}, { false, true}, { "Hello", "World"}
};
// should become 3 x 2 x 2 = 12 cases { {1, false, "Hello"}, ... , {3, true, "World"} }
std::vector< std::tuple<int, bool, std::string> > test_cases = cartesian_product( input );
// can write flat single loop over all cases
for (auto t: test_cases) {
BOOST_CHECK(MyType(t).my_test());
}
是否有任何(Boost)库可以做到这一点开箱即用?如何参与编写可变模板?
http://ideone.com/ThhAoa
没那么棘手:
#include <cstddef>
#include <utility>
#include <vector>
#include <tuple>
#include <string>
#include <iostream>
using std::size_t;
template<size_t...> struct seq {};
template<size_t Min, size_t Max, size_t... s>
struct make_seq:make_seq< Min, Max-1, Max-1, s... > {};
template<size_t Min, size_t... s>
struct make_seq< Min, Min, s... > {
typedef seq<s...> type;
};
template<size_t Max, size_t Min=0>
using MakeSeq = typename make_seq<Min, Max>::type;
size_t product_size() {
return 1;
}
template<typename... Sizes>
size_t product_size( size_t x, Sizes... tail ) {
return x * product_size(tail...);
}
namespace details {
template<typename max_iterator, typename Lambda>
void for_each_index( max_iterator mbegin, max_iterator mend, Lambda&& f, std::vector<size_t>& idx ) {
if (mbegin == mend) {
f(idx);
} else {
for (size_t i = 0; i < *mbegin; ++i) {
idx.push_back(i);
for_each_index(mbegin+1, mend, f, idx);
idx.pop_back();
}
}
}
template<typename Lambda>
void for_each_index( std::vector<size_t> const& maxes, Lambda&& f ) {
std::vector<size_t> idx;
details::for_each_index( maxes.begin(), maxes.end(), f, idx );
}
template<size_t... s, typename... Ts>
std::vector< std::tuple<Ts...> > does_it_blend( seq<s...>, std::tuple< std::vector<Ts>... >const& input ) {
std::vector< std::tuple<Ts...> > retval;
retval.reserve( product_size( std::get<s>(input).size()... ) );
std::vector<size_t> maxes = {
(std::get<s>(input).size())...
};
for_each_index( maxes, [&](std::vector<size_t> const& idx){
retval.emplace_back( std::get<s>(input)[idx[s]]... );
});
return retval;
}
}
template<typename... Ts>
std::vector< std::tuple<Ts...> > does_it_blend( std::tuple< std::vector<Ts>... >const& input ) {
return details::does_it_blend( MakeSeq< sizeof...(Ts) >(), input );
}
int main() {
std::tuple< std::vector<int>, std::vector<bool>, std::vector<std::string> > input {
{ 1, 2, 3}, { false, true}, { "Hello", "World"}
};
// should become 3 x 2 x 2 = 12 cases { {1, false, "Hello"}, ... , {3, true, "World"} }
std::vector< std::tuple<int, bool, std::string> > test_cases = does_it_blend( input );
for( auto&& x:test_cases ) {
std::cout << std::get<0>(x) << "," << std::get<1>(x) << "," << std::get<2>(x) << "n";
}
}
这里我创建了一个函数,它对可能的索引做笛卡尔积,然后直接在输出容器中创建元组。
我还做了保留输出大小的麻烦。
现在代码更少了
这有帮助吗?
#include <vector>
#include <tuple>
#include <type_traits>
template <typename... T>
struct transpose {};
template <typename... T>
struct transpose<std::tuple<std::vector<T>...>>
{
using type = std::vector<std::tuple<T...>>;
};
template <typename... T>
struct transpose<std::vector<std::tuple<T...>>>
{
using type = std::tuple<std::vector<T>...>;
};
int main()
{
std::tuple<std::vector<int>, std::vector<bool>> var;
static_assert(
std::is_same<
transpose<decltype(var)>::type,
std::vector<std::tuple<int, bool>>
>::value, ""
);
}
相关文章:
- 将元组的向量转换/构造为堆
- 将元组的向量构造成堆
- 元组由 Swig 生成的 Python 包装器返回,用于C++向量
- 我正在寻找一种优雅的方式来从元组向量创建tuple_element向量
- 如何在元组初始化向量中删除样板?
- c++:交换向量中所有元组的第一个和第二个元素
- 如何在C++中创建元组向量?
- 返回两个向量 – 使用引用还是元组?
- 将可变参数模板包装到元组向量
- C++ 从模板参数创建元组向量
- 随机访问元组向量中的元组值
- 如何构造元组向量并像配对一样对它们进行排序?
- 通过移动从两个向量创建元组向量
- 使用GCC v4.8在Ubuntu 14.04上定义C 11中元组向量时的编译错误
- 在元组向量中查找特定的元组元素
- 如何使用 C++11 可变参数模板来定义由向量元组支持的元组向量
- c++中的元组向量
- 查找boost元组向量中元素的位置
- 自定义对元组向量进行排序
- 自定义排序元组向量时出错