Следующее должно работать, хотя я использовал некоторую свободу, используя вместо этого std::array
. Это немного более удобно.
Каждый вызов value_getter<size,I>::get<T>
принимает std::array<T,2>
в качестве аргумента и обрезает на основе signs[I]
таким образом мы получаем arr[signs[I]
типа T, который снова Вложенный массив (если я! = Размер), поэтому мы снова называем value_getter<size,I>::get
с T в качестве аргумента.
Помощник value_getter
struct, чтобы обрезать вложенные массивы по частям.
template <std::size_t size, std::size_t I> struct value_getter {
template <typename T>
static double& get(std::array<T,2>& arr, const std::array<bool, size>& signs) {
return value_getter<size, I+1>::template get(arr[signs[I]], signs);
}
};
Конечный базовый футляр, возвращающий ссылку на стоимость.
template <std::size_t size> struct value_getter<size, size> {
static template <typename T> double& get(T& arr, const std::array<bool, size>& signs) {
return arr;
}
};
Использование:
std::array< std::array< std::array< double, 2>, 2>, 2> values{};
std::array<bool, 3> signs{};
double v = value_getter<3,0>::template get(values, signs);
Demo
Я размышлял о том, как заставить его работать со стилем массива C, хотя, проблема заключается в том, чтобы представить тип std::array<T,2>
в функции ::get
, Его можно заставить работать чем-то вроде std::add_pointer<T>
, который должен дать T*
от T
.
Так что на самом деле это намного проще в массивах стилей C.
Здесь T
будет обозначать сам массив. Если мы обходим какую-либо статическую проверку ошибок, T в основном не используется как тип. Поскольку мы знаем, что arr
типа T является массивом (если I != size
), то мы всегда можем позвонить operator[]
по адресу arr
.
template <std::size_t size, std::size_t I> struct value_getter {
template <typename T>
static double& get(T arr, bool *signs) {
return value_getter<size, I+1>::template get(arr[signs[I]], signs);
}
};
Базовый корпус снова тривиален.
template <std::size_t size> struct value_getter<size, size> {
static double& get(double& arr, bool * signs) {
return arr;
}
};
Demo(C array)