Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.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++20将多维数组的维数推断为参数包_C++_Arrays_Variadic Templates_C++20 - Fatal编程技术网

C++20将多维数组的维数推断为参数包

C++20将多维数组的维数推断为参数包,c++,arrays,variadic-templates,c++20,C++,Arrays,Variadic Templates,C++20,我正在以多维数组的形式实现一个容器。我正在尝试复制一个函数,该函数使用多维数组从一维内置数组创建std::array: 样板 constexpr mdarray to_mdarrayT&a[N]; int-arr[5][12]{}; 致_mdarrayarr;//返回mdarray 我想将内置数组的维数推断为N,并返回相应的mdarray。我还没有找到正确的语法,我总是以错误告终。要么我没有正确展开包,要么编译器认为我试图声明函数指针或lambda。我也没有在网上找到任何资源 到目前为止,我找到

我正在以多维数组的形式实现一个容器。我正在尝试复制一个函数,该函数使用多维数组从一维内置数组创建std::array:

样板 constexpr mdarray to_mdarrayT&a[N]; int-arr[5][12]{}; 致_mdarrayarr;//返回mdarray 我想将内置数组的维数推断为N,并返回相应的mdarray。我还没有找到正确的语法,我总是以错误告终。要么我没有正确展开包,要么编译器认为我试图声明函数指针或lambda。我也没有在网上找到任何资源

到目前为止,我找到了两种选择。一种是将数组分解成指针,让用户指定维度

样板 constexpr mdarray to_mdarrayT*const a; int-arr[5][12]{}; 杜姆达拉亚尔; 我发现另一个在里面。它涉及使用递归宏生成N维重载:

定义大小\u T\u S\u 1大小\u T N 定义大小\u T\u S\u 2大小\u T\u S\u 1,大小\u T M 定义大小\u T\u S\u 3大小\u T\u S\u 2,大小\u T L 定义括号_S_1[N] 定义括号_S_2括号_S_1[M] 定义括号3括号2[L] 定义字母\u S\u 1 N 定义字母\u S_2字母\u S_1,M 定义字母\u S_3字母\u S_2,L 定义到\u MD\u Ndim模板\ constexpr mdarray到_mdarray和值括号_S_dim; 至_MD_N1; 至_MD_N2; 致MD_N3; //相当于: //至MD_N1 样板 constexpr mdarray to_mdarrayT&value[N]; //至_MD_N2 样板 constexpr mdarray to_mdarrayT&value[N][M]; //至第3页 样板 constexpr mdarray to_mdarrayT&value[N][M][L]; 这两种解决方案都有缺陷。一个要求用户输入正确的维度,另一个要求多次定义相同的函数并限制维度的数量


在C++20中有什么方法可以做到这一点,还是目前还不可能做到这一点?

不幸的是,我通常的Boost.Mp11一行程序的趋势将在这里结束,因为Boost.Mp11并不能很好地处理值,我们需要将int[5][12]转换为mdarray,并且没有简单的机制使用该库来实现这一点

相反,我们只是手工操作。提供第n个区段和区段数。将其与make_index_序列相结合,您可以获得所有这些:

样板 结构mdarray_用于_impl; 样板 struct mdarray_for_impl version无论如何都需要一对助手别名

//仅限类型的mdarray 样板 使用mdarray\u t=mdarray; //仅限类型的范围 样板 使用mp_范围=mp_大小\u t; 然后允许:

样板 将mdarray_用于2= mp_申请 >>; 这是与以前相同的算法,除了mp_iota_c获得数据块索引序列而不是std::make_index_序列,然后mp_transform_q获得第n个数据块,而不是直接在包扩展中使用它


在本例中,对于int[5][12],我们建立mp_列表,因为我们都是类型,没有值,然后mp_apply将其转换为mdarray\t,从而将其转换为mdarray。

不幸的是,我通常使用的Boost.Mp11一行程序将在这里结束,因为Boost.Mp11不能很好地处理值,我们需要转换int[5][12]在mdarray中,没有简单的机制可以使用该库实现这一点

相反,我们只是手工操作。提供第n个区段和区段数。将其与make_index_序列相结合,您可以获得所有这些:

样板 结构mdarray_用于_impl; 样板 struct mdarray_for_impl version无论如何都需要一对助手别名

//仅限类型的mdarray 样板 使用mdarray\u t=mdarray; //仅限类型的范围 样板 使用mp_范围=mp_大小\u t; 然后允许:

样板 将mdarray_用于2= mp_申请 >>; 这是与以前相同的算法,除了mp_iota_c获得数据块索引序列而不是std::make_index_序列,然后mp_transform_q获得第n个数据块,而不是直接在包扩展中使用它

在本例中,对于int[5][12],我们建立了mp_列表,因为我们都是类型,没有值,然后mp_apply将其转换为mdarray,mdarray将其转换为mdarray

我想将内置数组的维数推断为N,并返回相应的mdarray

也许。。。用一点递归

template <std::size_t ... Ns, typename T>
constexpr mdarray<std::remove_cv_t<T>, Ns...> get_mdarray_t (T const &)
 { return {}; }

template <std::size_t ... Ns, typename T, std::size_t N>
constexpr auto get_mdarray_t (T const (&arr)[N])
 { return get_mdarray_t<Ns..., N>(arr[0]); }
下面是一个完整的编译C++11示例

#include <utility>

template <typename, std::size_t...>
struct mdarray
 { };

template <std::size_t ... Ns, typename T>
constexpr mdarray<std::remove_cv_t<T>, Ns...> get_mdarray_t (T const &)
 { return {}; }

template <std::size_t ... Ns, typename T, std::size_t N>
constexpr auto get_mdarray_t (T const (&arr)[N])
 { return get_mdarray_t<Ns..., N>(arr[0]); }

template <typename T>
using mdarray_t = decltype(get_mdarray_t<>(std::declval<T>()));

int main ()
 {
   using A0 = int;
   using A1 = int[2u];
   using A2 = int[2u][3u];
   using A3 = int[2u][3u][5u];

   using T0 = mdarray_t<A0>;
   using T1 = mdarray_t<A1>;
   using T2 = mdarray_t<A2>;
   using T3 = mdarray_t<A3>;

   using U0 = mdarray<int> ;
   using U1 = mdarray<int, 2u>;
   using U2 = mdarray<int, 2u, 3u>;
   using U3 = mdarray<int, 2u, 3u, 5u>;

   static_assert( std::is_same<T0, U0>::value, "!" );
   static_assert( std::is_same<T1, U1>::value, "!" );
   static_assert( std::is_same<T2, U2>::value, "!" );
   static_assert( std::is_same<T3, U3>::value, "!" );
 }
我想将内置数组的维数推断为N,并返回相应的mdarray

也许。。。用一点递归

template <std::size_t ... Ns, typename T>
constexpr mdarray<std::remove_cv_t<T>, Ns...> get_mdarray_t (T const &)
 { return {}; }

template <std::size_t ... Ns, typename T, std::size_t N>
constexpr auto get_mdarray_t (T const (&arr)[N])
 { return get_mdarray_t<Ns..., N>(arr[0]); }
下面是一个完整的编译C++11示例

#include <utility>

template <typename, std::size_t...>
struct mdarray
 { };

template <std::size_t ... Ns, typename T>
constexpr mdarray<std::remove_cv_t<T>, Ns...> get_mdarray_t (T const &)
 { return {}; }

template <std::size_t ... Ns, typename T, std::size_t N>
constexpr auto get_mdarray_t (T const (&arr)[N])
 { return get_mdarray_t<Ns..., N>(arr[0]); }

template <typename T>
using mdarray_t = decltype(get_mdarray_t<>(std::declval<T>()));

int main ()
 {
   using A0 = int;
   using A1 = int[2u];
   using A2 = int[2u][3u];
   using A3 = int[2u][3u][5u];

   using T0 = mdarray_t<A0>;
   using T1 = mdarray_t<A1>;
   using T2 = mdarray_t<A2>;
   using T3 = mdarray_t<A3>;

   using U0 = mdarray<int> ;
   using U1 = mdarray<int, 2u>;
   using U2 = mdarray<int, 2u, 3u>;
   using U3 = mdarray<int, 2u, 3u, 5u>;

   static_assert( std::is_same<T0, U0>::value, "!" );
   static_assert( std::is_same<T1, U1>::value, "!" );
   static_assert( std::is_same<T2, U2>::value, "!" );
   static_assert( std::is_same<T3, U3>::value, "!" );
 }
也许会有帮助,也许会有帮助