У меня есть шаблон класса со следующей спецификацией:
template <typename T, size_t... Dims> class Array;
И сказать, что это можно использовать следующим образом:
// Define a 2X3X4 array of integers. Elements are uninitialized.
Array<int, 2, 3, 4> a, b;
Array<short, 2, 3, 4> c;
Array<int, 0> e1; // This line must cause a compile-time error.
Как я могу достичь этой функциональности? Я подумал, что если бы я мог извлечь весь список аргументов, я мог бы тогда создать n-мерный массив как прямой рекурсивный вызов. Как я могу сделать это сейчас
Вы можете создать черту времени компиляции, которая делает то, что вы хотите:
#include <type_traits>
template <std::size_t... Ts>
struct not_zero {};
template <std::size_t N>
struct not_zero<N> : std::integral_constant<bool, N> {};
template <std::size_t N, std::size_t... Ts>
struct not_zero<N, Ts...> : std::integral_constant<bool, N && not_zero<Ts...>::value> {};
template <typename T, std::size_t... Ts>
struct Array
{
static_assert(not_zero<Ts...>::value, "Dimension cannot be 0");
};
template struct Array<int, 3>; // OK
template struct Array<int, 3, 2, 1, 0>; // error: static assertion failed: Dimension cannot be 0
Посмотреть демо Вот.
Создайте для него специализацию:
#include <iostream>
template <typename T, std::size_t... Dims>
struct Array {};
template <typename T>
struct Array<T, 0>; // leave as an incomplete type
int main()
{
Array<int, 3> x; // OK
Array<int, 0> y; // error: aggregate ‘Array<int, 0u> y’ has incomplete type and cannot be defined
}
Что-то вроде этого может быть
namespace mine {
template<typename T, size_t first, size_t... rest>
struct multi_array__ {
enum { dims = sizeof...(rest) };
static_assert(first,"dimension can not be zero!");
typedef std::array< typename multi_array__<T, rest...>::type, first > type;
};template<typename T, size_t first>
struct multi_array__<T,first> {
enum { dims = 1 };
static_assert(first,"dimension can not be zero!");
typedef std::array<T,first> type;
};
template <typename T, std::size_t... ds>
using multi_array = typename multi_array__<T, ds ...>::type;
};
Вы можете использовать это так
mine::multi_array <int,2,3,4> arr1 = {};
// multi_array<int,2,3,0,4> arr3; // This fails
mine::multi_array <int,3,4> arr2 = {};
Задания, как эта работа тоже
arr2[0] = arr1[0][0];
Here
простая тестовая программа