Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;11变量编程,如何定义向量塔_C++_Templates_C++11_Metaprogramming_C++14 - Fatal编程技术网

C++ c++;11变量编程,如何定义向量塔

C++ c++;11变量编程,如何定义向量塔,c++,templates,c++11,metaprogramming,c++14,C++,Templates,C++11,Metaprogramming,C++14,如何(如果可能的话)使用c++11变量编程来定义函数体中的一系列向量(或者换句话说,一系列N-维数组,递减N,直到0),如下面的变量 vector<vector<vector<int>>> v<3>; vector<vector<int>> v<2>; vector<int> v<1>; int v<0>; 向量v; 向量v; 向量v; INTV; 我想象的是: #incl

如何(如果可能的话)使用c++11变量编程来定义函数体中的一系列
向量(或者换句话说,一系列
N
-维数组,递减
N
,直到0),如下面的变量

vector<vector<vector<int>>> v<3>;
vector<vector<int>> v<2>;
vector<int> v<1>;
int v<0>;
向量v; 向量v; 向量v; INTV;
我想象的是:

#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;
}
#包括
#包括
使用名称空间std;
模板结构seq{};
模板结构gens:gens{};
模板结构gens{typedef seq type;};
模板
无效f(序号){
//如何在这里写出v的定义?

vector您可以找到一个类似的问题,但在以下位置处理
std::map

这里有一个用于
std::vector

#include <iostream>
#include <vector>

template<int N, typename V>
struct NVector { typedef std::vector<typename NVector<N-1, V>::type> type; };

template<typename V>
struct NVector<1, V> { typedef std::vector<V> type; };

int main(int argc, const char *argv[]) {

   NVector<1, int>::type v1(10, 0);

   NVector<2, int>::type v2;
   v2.push_back(v1);

   NVector<3, int>::type v3;
   v3.push_back(v2);

   for ( int i = 0; i < 10; ++i )
   {
      std::cout << v3[0][0][i] << " ";
   }
   std::cout << std::endl;
}
如果您想通过假设值类型为
int
来简化它,可以使用:

#include <iostream>
#include <vector>

template<int N, typename V>
struct NVector { typedef std::vector<typename NVector<N-1, V>::type> type; };

template<typename V>
struct NVector<1, V> { typedef std::vector<V> type; };

template<int N>
using V = typename NVector<N, int>::type;

int main(int argc, const char *argv[]) {

   V<1> v1(10, 0);

   V<2> v2;
   v2.push_back(v1);

   V<3> v3;
   v3.push_back(v2);

   for ( int i = 0; i < 10; ++i )
   {
      std::cout << v3[0][0][i] << " ";
   }
   std::cout << std::endl;
}
#包括
#包括
模板
结构变换器{typedef std::vector type;};
模板
结构变换器{typedef std::vector type;};
模板
使用V=typename NVector::type;
int main(int argc,const char*argv[]{
v1(10,0);
v2;
v2.推回(v1);
v3;
v3.推回(v2);
对于(int i=0;i<10;++i)
{

std::cout不需要变量,递归的
typedef
足以在编译时生成这些类型


是如何实施的?

1)提供一个包含两个参数的模板:向量元素类型(
T
),以及所需的结构维度(
size\T N
).Declare a typedef
type
:它将基于使用深度
N-1
实例化的模板的
type
声明,因此递归

template<typename T, size_t N>
struct VectorGenerator
{
    typedef std::vector< typename VectorGenerator<T, N-1>::type > type;
};
但是它不太可读,也不方便,而且非常冗长。让我们为我们的类型引入新名称

这是使用(C++11)
使用
关键字进行别名的最佳情况。我们有两种不同的别名方法:

1)为特定维度和类型声明一个别名,这里我们称之为V3,用于
N=3
T=double

VectorGenerator<double, 4>::type v; // v as a depth of 4 and handle double
using V3 = VectorGenerator<double, 3>::type;  // Alias

V3 v;                                         // Use the alias
对于@mpark给出的多个“塔”的通用元组生成,我在这里将其改编为我的代码示例:

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;
模板
结构标识{using type=T;};
//通过在gen_塔上映射索引_序列,生成塔的元组。
模板
std::tuple gen\u towers\u impl(std::integer\u序列);
//为N创建索引序列,并使用gen\u towers\u impl。
模板
建筑大楼
:标识{};
//方便类型别名
模板
使用gen_towers_t=typename gen_towers::type;
您需要
-std=c++1y
来编译它(包括
标题)


请参阅一个工作示例。

我不会在生成单个塔时进行太多的详细说明,因为这里有其他答案对其进行了解释。这是我的
gen_-tower
版本,它生成一个向量深度
I
的塔

例如,
gen\u tower\t
std::vector

#include <iostream>
#include <vector>

template<int N, typename V>
struct NVector { typedef std::vector<typename NVector<N-1, V>::type> type; };

template<typename V>
struct NVector<1, V> { typedef std::vector<V> type; };

int main(int argc, const char *argv[]) {

   NVector<1, int>::type v1(10, 0);

   NVector<2, int>::type v2;
   v2.push_back(v1);

   NVector<3, int>::type v3;
   v3.push_back(v2);

   for ( int i = 0; i < 10; ++i )
   {
      std::cout << v3[0][0][i] << " ";
   }
   std::cout << std::endl;
}
例子
static_断言(std::is_same::value,”);
静态断言(std::是否相同<
发电塔,
标准::向量>::值“”;
静态断言(std::是否相同<
第二代塔楼,
标准::元组>::值“”;
静态断言(std::是否相同<
第二代塔楼,
标准::元组>::值“”;
int main(){}

你能举例说明你打算如何使用这N个数组吗,或者这是一个定义它们的练习吗?@Alf,这纯粹是出于个人兴趣。请在P.S.cheers中查看更新。谢谢。有没有办法将结果定义为v,v??请查看我的更新。@R Sahu。我想我真正想要的是生成一个元组参数N或参数包的(v1,v2,…,v_N)(基于您展示的内容)。请参阅我的编辑。Thanks@TingL,如果不看一个用例,就很难提出你想要什么。我希望你有足够的答案来运行它。非常感谢boost多维数组的答案和指针。有没有一种方法可以将结果写成v,v?请看我的更新。你是什么意思y?我不清楚你说的“V”是什么意思是我的V3,我猜。不是吗?@TingL
模板使用V=VectorGenerator;
V;
,这非常聪明。我知道如何用宏实现这一点,但我以前从未在模板中看到过。我会按照通常的惯例,将
:value
更改为
:type
,否则答案不错。
using V3 = VectorGenerator<double, 3>::type;  // Alias

V3 v;                                         // Use the alias
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;
}
auto tower = std::tuple<V<1>, V<2>, V<3>>(v1, v2, v3);
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;
// Useful for defining meta-functions compactly.
template <typename T>
struct identity { using type = T; };
// Forward declaration.
template <typename T, std::size_t I>
struct gen_tower;

// Convenience type alias.
template <typename T, std::size_t I>
using gen_tower_t = typename gen_tower<T, I>::type;

// Base case.
template <typename T>
struct gen_tower<T, 0> : identity<T> {};

// Wrap std::vector around tower of depth I - 1.
template <typename T, std::size_t I>
struct gen_tower : identity<std::vector<gen_tower_t<T, I - 1>>> {};
// Generate a tuple of towers by mapping index_sequence over gen_tower.
template <typename T, std::size_t... Is>
std::tuple<gen_tower_t<T, Is>...> gen_towers_impl(std::index_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;
static_assert(std::is_same<gen_tower_t<int, 0>, int>::value, "");

static_assert(std::is_same<
                  gen_tower_t<int, 2>,
                  std::vector<std::vector<int>>>::value, "");

static_assert(std::is_same<
                  gen_towers_t<int, 2>,
                  std::tuple<int, std::vector<int>>>::value, "");

static_assert(std::is_same<
                  gen_towers_t<int, 3>,
                  std::tuple<int,
                             std::vector<int>,
                             std::vector<std::vector<int>>>>::value, "");

int main() {}