c ++ 11可变参数编程,如何定义向量塔

天花

我如何(如果可能的话)如何使用c ++ 11可变参数编程vector在函数体中定义一系列“ ”(或换句话说,一个N由-递减N到0的-维数组序列),就像下面的变量一样?

vector<vector<vector<int>>> v<3>;
vector<vector<int>> v<2>;
vector<int> v<1>;
int v<0>;

我想象的是这样的:

#include <iostream>
#include <vector>
using namespace std;

template<int ...> struct seq {};
template<int N, int ...S> struct gens : gens<N-1, N-1, S...> {};
template<int ...S> struct gens<0, S...>{ typedef seq<S...> type; };

template<int ...S>
void f(seq<S...>) {
  //how do I write definitions of v<N> here?
  vector<vector<...(N layers)<vector<int> ...> v<N>;     //??how-to, not valid c++
  vector<vector<...(N -1 layers)<vector<int> ...> v<N-1>;//??how-to, not valid c++
  //...
  vector<int> v<1>;  //??how-to, not valid c++
  int v<0>;          //??how-to, not valid c++

  //...
}

int main() {
  f(typename gens<3>);
  return 0;
}

另外,这在c ++ 14中会更容易吗?

谢谢,

- 编辑 -

为了明确起见,我所说的“向量塔”最好用一个N元组(v_1,v_2,...,v_N)描述,其中N是一个不可或缺的模板参数。v_1是向量,v_2是向量>,依此类推。

-编辑2--

到目前为止,quantdev和R的答案已成功解决了为任何固定N(例如3)定义N元组的问题,但无法为未指定的N生成元组N除了答案中的功能外,我还需要一个可以像gen_tower<N>return一样使用的功能tuple(v1,v2,...,vN)

考虑使用可变参数编程来计算阶乘的示例。除了能够手动写出任何特定表达式的能力之外,我还需要一个函数来计算factorial<N>()任何因子(这就是为什么我询问可变参数编程以及是否会使它变得更容易的原因。)N<1*2*3>c++14

聚苯乙烯

纯粹出于个人利益,我希望此序列希望实现一个通用功能,该功能可以从文件读取N维数组。我尚不清楚确切的方法,但是我认为在第一步中,我应该能够定义finalN维数组,以及from至to的中间k维数组我可以读取2维数组和3维数组。但是能够读取任何尺寸的数组将是很好的。kN-11

量子开发

不需要variadics,递归typedef就足以在编译时生成这些类型。


如何实施?

1)提供一个带有2个参数的模板:矢量元素类型(T)和结构的所需尺寸(size_t N)。声明一个typedef type:它将基于type使用depth实例化的模板的声明N-1,因此是递归的。

template<typename T, size_t N>
struct VectorGenerator
{
    typedef std::vector< typename VectorGenerator<T, N-1>::type > type;
};

2)提供用于终止递归的终止条件,这里是维度为0的模板的特殊化,声明了common的类型std::vector<T>

template<typename T>
struct VectorGenerator<T, 0>
{
    typedef std::vector<T> type;
};

如何使用它 ?

现在我们可以声明一个v类型的向量VectorGenerator<T, N>::type

VectorGenerator<double, 4>::type v; // v as a depth of 4 and handle double

但这不是很可读或不方便,而且很冗长。让我们为我们的类型引入新名称。

这是模板别名的完美案例,使用(C ++ 11)using关键字作为别名。我们有2种不同的别名方式:

1)为特定的尺寸和类型声明别名,在这里我们将其称为N=3和的V3 T=double

using V3 = VectorGenerator<double, 3>::type;  // Alias

V3 v;                                         // Use the alias

或者,

2)为特定类型声明模板别名,将维度保留为模板参数:

template <size_t N> 
using V = typename VectorGenerator<double, N>::type;  // Alias

V<3> v;                                              // Use the Alias

最终代码示例:

template<typename T, size_t N>
struct VectorGenerator
{
    typedef std::vector< typename VectorGenerator<T, N-1>::type > type;
};

template<typename T>
struct VectorGenerator<T, 0>
{
    typedef std::vector<T> type;
};

// Alias for V3, V2 ... usage
using V3 = VectorGenerator<double, 3>::type;
using V2 = VectorGenerator<double, 2>::type;

// Alias for V <k> usage
template <size_t N> 
using V = typename VectorGenerator<double, N>::type;

int main() {

    V<3> v3;
    V<2> v2;
    v3.push_back(v2);
    return 0;
}

注意事项:

  • 考虑Boost多维数组库
  • 我不确定您的最终目标是什么,但这可能是一个过大的杀伤力。
  • 至于您的第二次编辑,tuple现在很容易声明带有多个不同维的向量:

例子:

auto tower = std::tuple<V<1>, V<2>, V<3>>(v1, v2, v3);

对于生成多个“塔”的通用元组,@ mpark提供了一个有效的C ++ 14解决方案,在这里将其调整为我的代码示例:

template <typename T>
struct identity { using type = T; };

// Generate a tuple of towers by mapping index_sequence over gen_tower.
template <typename T, std::size_t... Is>
std::tuple<VectorGenerator<T, Is>...> gen_towers_impl(std::integer_sequence<Is...>);

// Make an index_sequence for N and use gen_towers_impl.
template <typename T, std::size_t N>
struct gen_towers
    : identity<decltype(gen_towers_impl<T>(std::make_index_sequence<N>()))> {};

// Convenience type aliases
template <typename T, std::size_t N>
using gen_towers_t = typename gen_towers<T, N>::type;

您将需要对其-std=c++1y进行编译(包括include<utility><tuple>headers)

在这里查看工作示例

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何使用C ++ 11可变参数模板定义由向量元组支持的向量元组?

c ++ 11:使用向量的元素调用可变参数函数,并自动推导参数数量

如何在C ++ 17中创建从可变参数模板推导的向量类型的元组?

c ++ 11递归可变参数模板

C ++ 11中的定长可变参数包

如何在C ++ 11中实现可变参数模式以将可变数量的参数转发给函数?

C ++可变参数模板迭代向量并比较元素

C ++ 14从可变参数模板创建向量

在 C 中定义具有可变长度向量的结构

C ++ 11:可变参数模板函数参数的数量?

如何将可变参数模板转换为多个单个模板?(C ++竞争编程调试模板)

如何在 C++ 中定义接受不同参数类型的函数向量?

模板编程向量C ++

c ++ 11可变参数模板无法编译

调用类内的函数的C ++ 11可变参数模板

C ++ 11 constexpr可变参数逻辑表达式

C ++ 11:可变参数模板推导逻辑

C ++ 11中的可变参数模板和多重继承

C ++ 11可变参数模板和std :: endl

C ++ 11可变数量的参数,相同的特定类型

通过可变参数模板的C ++ 11构造函数继承

具有可变参数std :: function的C ++ 11函数签名

C ++ 11翻译可变参数模板以推断类类型

C ++ 11可变参数模板函数存储

(C ++ 11)可变参数模板序列打印

c ++ 11语法可变参数模板随rebind扩展

向量(在 C++ 中)如何分配可变大小的元素?

用于定义typedef的可变参数模板(使用C ++ 98)

在C ++中为可变参数模板定义子包