【发布时间】:2021-07-04 19:19:02
【问题描述】:
我正在以多维数组的形式实现一个容器。我正在尝试复制std::to_array (C++ 20),这是一个使用我的多维数组从一维内置数组创建std::array 的函数:
template<typename T, std::size_t... N>
constexpr mdarray<std::remove_cv_t<T>, N...> to_mdarray(T (&a)[N]));
int arr[5][12]{};
to_mdarray(arr); // Returns mdarray<int, 5, 12>
我想将内置数组的维度推导出为N,并返回对应的mdarray。我还没有设法找出正确的语法,我总是以错误告终。要么我没有正确展开包,要么编译器认为我正在尝试声明一个函数指针或 lambda。我也没有在网上找到任何资源。
到目前为止,我找到了两种选择。一种是将数组衰减为指针,让用户指定维度。
template<typename T, std::size_t... N>
constexpr mdarray<std::remove_cv_t<T>, N...> to_mdarray(T* const a);
int arr[5][12]{};
to_mdarray<5, 12>(arr);
我在blog from Stanislav Arnaudov 中找到了另一个。它涉及使用递归宏生成第 N 维重载:
#define SIZE_T_S_1 size_t N
#define SIZE_T_S_2 SIZE_T_S_1 , size_t M
#define SIZE_T_S_3 SIZE_T_S_2 , size_t L
#define BRACKETS_S_1 [N]
#define BRACKETS_S_2 BRACKETS_S_1[M]
#define BRACKETS_S_3 BRACKETS_S_2[L]
#define LETTERS_S_1 N
#define LETTERS_S_2 LETTERS_S_1, M
#define LETTERS_S_3 LETTERS_S_2, L
#define TO_MD_N(dim) template<typename T, SIZE_T_S_##dim> \
constexpr mdarray<std::remove_cv_t<T>, LETTERS_S_##dim> to_mdarray(T (&values) BRACKETS_S_##dim);
TO_MD_N(1);
TO_MD_N(2);
TO_MD_N(3);
// Equivalent to:
// TO_MD_N(1)
template<typename T, std::size_t N>
constexpr mdarray<std::remove_cv_t<T>, N> to_mdarray(T (&values)[N]);
// TO_MD_N(2)
template<typename T, std::size_t, std::size_t M>
constexpr mdarray<std::remove_cv_t<T>, N, M> to_mdarray(T (&values)[N][M]);
// TO_MD_N(3)
template<typename T, std::size_t, std::size_t M, std::size_t L>
constexpr mdarray<std::remove_cv_t<T>, N, M, L> to_mdarray(T (&values)[N][M][L]);
这两种解决方案都有缺陷。一种要求用户输入正确的维度,另一种需要多次定义相同的函数并限制维度的数量。
在 C++20 中有什么方法可以做到这一点,还是目前不可能?
【问题讨论】:
-
std::rank和std::extent可能会有所帮助
标签: c++ arrays variadic-templates c++20