C++: мысли об инициализации вложенных векторов.
Главная идея изложенного ниже в следующем. Мне не нравятся попытки инициализировать многомерные массивы динамически, будь то вектора или простые массивы, прямо в коде. Это выглядит чрезвычайно громоздко, длинно, а главное, не очень понятно:
vector<vector<vector<int>>> arr(
2,
vector<vector<int>>(
3,
vecotr<int>(5, 0)
)
);
Поэтому я попытался вынести всю эту работу в одну функцию, которую мы вам разрешаем использовать…
Только вот пытаться понять, что тут происходит, не надо ;)
#include <bits/stdc++.h>
namespace ldv {
using std::vector;
using std::size_t;
template<typename T, typename... Args>
struct __init_vectors_of;
template<typename T>
struct __init_vectors_of<T> {
using type = T;
static inline type get(T const& value) {
return value;
}
};
template<typename T, typename Head, typename... Tail>
struct __init_vectors_of<T, Head, Tail...> {
using under = __init_vectors_of<T, Tail...>;
using inside = typename under::type;
using type = vector<inside>;
static inline type get(T const& value, Head head, Tail... tail) {
return type(head, under::get(value, tail...));
}
};
template<typename T, typename... Args>
struct __init_array_of;
template<typename T>
struct __init_array_of<T> {
using type = T;
static inline type get(T const& value) {
return value;
}
};
template<typename T, typename Head, typename... Tail>
struct __init_array_of<T, Head, Tail...> {
using under = __init_array_of<T, Tail...>;
using inside = typename under::type;
using type = inside*;
static inline type get(T const& value, Head head, Tail... tail) {
type p = new inside[head];
for (size_t i = 0; i != head; ++i) {
p[i] = under::get(value, tail...);
}
return p;
}
};
/**
* Usage: init_vectors_of(default value, <sizes of dimensions>)
*/
template<typename T, typename... Args>
inline typename __init_vectors_of<T, Args...>::type init_vectors_of(T const& value, Args... sizes) {
return __init_vectors_of<T, Args...>::get(value, sizes...);
}
/**
* Usage: init_array_of(default value, <sizes of dimensions>)
*/
template<typename T, typename... Args>
inline typename __init_array_of<T, Args...>::type init_array_of(T const& value, Args... sizes) {
return __init_array_of<T, Args...>::get(value, sizes...);
}
}
using ldv::init_vectors_of;
using ldv::init_array_of;
using std::vector;
int main() {
// Создать 2-элементный вектор из 3-элементных векторов из 5-элементных векторов из нулей:
vector<vector<vector<int>>> arr = init_vectors_of<int>(0, 2, 3, 5);
// То же самое на массивах:
int*** arr2 = init_array_of<int>(0, 2, 3, 5);
}