元组的可变参数生成
Variadic Generation of Tuples
我想编写一个基于整数值和协调的 c++ 代码,生成一组元组和函数调用,如下所示:
// dimension = 1, input = (i) generated tuples: (i-1) (i), (i+1)
// dimension = 2, input = (i,j) generated tuples: (i-1, j), (i, j-1), (i, j),(i+1, j), (i, j+1)
<typename Index, int dimension>
void my_function(Index input)
{
// some magic here that generates the following code or sth like this
get_value(generated_tuple0);
get_value(generated_tuple1);
....
....
get_value(generated_tupleN);
}
我不擅长模板编程,也许在 C++11 中使用可变参数是可能的。
假设索引是一个元组,这是一个可能的解决方案:
template <class Index, int I, int dimension>
struct tuple_builder_t
{
static void build(std::vector<Index> &result, Index center)
{
Index iter = center;
for (int i = -1; i < 2; i++)
{
std::get<I - 1>(iter) = std::get<I - 1>(center) +i;
tuple_builder_t<Index, I, dimension>::build(result, iter);
}
}
};
template <class Index, int dimension>
struct tuple_builder_t<Index, dimension, dimension>
{
static std::vector<Index> build(std::vector<Index> &result, Index center)
{
Index iter = center;
for (int i = -1; i < 2; i++)
{
std::get<dimension - 1>(iter) = std::get<dimension - 1>(center) +i;
result.push_back(iter);
}
}
};
template <class Index, int dimension>
void my_function(Index index)
{
std::vector<Index> result;
tuple_builder_t<Index, 1, dimension>::build(result, index);
}
这是一个巧妙的问题,我已经发现自己在类似的东西面前(迭代超立方体的维度)
这是一个编译时解决方案。它动态生成所需的元组,并使用这些元组调用传递的函数。
template<typename TupleType, typename FunctionType, size_t N, typename = std::enable_if_t<N != std::tuple_size<std::decay_t<TupleType> >::value> > //why SFINAE required?
void tuple_caller_impl(TupleType&& t, FunctionType&& f, std::integral_constant<size_t, N>)
{
--std::get<N>(t); f(t); ++std::get<N>(t);
++std::get<N>(t); f(t); --std::get<N>(t);
tuple_caller_impl(std::forward<TupleType>(t), std::forward<FunctionType>(f), std::integral_constant<size_t, N+1>());
}
template<typename TupleType, typename FunctionType>
void tuple_caller_impl(TupleType&& t, FunctionType&& f, typename std::tuple_size<std::decay_t<TupleType> >::type)
{
f(std::forward<TupleType>(t)); // finally call function on the unchanged tuple
// could also be done by specializing the 0-th call to tuple_caller_impl
}
template<typename TupleType, typename FunctionType>
void tuple_caller(TupleType&& t, FunctionType&& f)
{
tuple_caller_impl(std::forward<TupleType>(t), std::forward<FunctionType>(f), std::integral_constant<size_t, 0>());
}
像应用一样应用
int main()
{
auto f = [](auto const& t) { std::cout<<"call function with ("<<std::get<0>(t)<<","<<std::get<1>(t)<<","<<std::get<2>(t)<<")"<<std::endl; };
auto t= std::make_tuple(1,5,3);
tuple_caller(t,f);
}
前面将以下内容打印到屏幕:
call function with (0,5,3)
call function with (2,5,3)
call function with (1,4,3)
call function with (1,6,3)
call function with (1,5,2)
call function with (1,5,4)
call function with (1,5,3)
演示
请注意,调用顺序与示例中的调用顺序不同。
相关文章:
- 在不传递参数数量且只有3个点的情况下,如何使用变差函数
- 如何使用可变参数模板强制转换每个变体类型
- 关于如何在具有单个参数的变体构造中选择替代方案?
- 调用参数排列不变函数 f(i++, i++)
- 参数归纳与标准::变体
- 模板化回调参数的逆变,如 C# 中的逆变
- 如何在没有参数包的情况下编写变差函数
- 通过具有嵌套类的工厂类获取多个变异类模板参数包
- 获取模板参数的成员变量值列表
- 保留短 lambda 用作函数的中间参数,使用 clang 格式保持不变
- 如何定义变体<x,y,z>提取模板参数的子类型
- 正确对齐内存模板,参数顺序不变
- 递归中不同参数类型的变元模板函数
- 通过函数指针传递给变差函数的参数会更改其值
- 提升预定义为带有参数的全局 lambda 的变体访问者
- 使用可变参数模板参数提升变体访问者
- boost ::变体 - 为什么模板参数比const字符串参数具有更高的优先级
- 将变参数包中的值加载到临时数组中
- 使用额外参数提升变体访客
- 正在将动态数组元素解析为参数?(变音符)