Более краткий способ объявить вектор высокой размерности - PullRequest
0 голосов
/ 25 октября 2018

Мне не нравится, как, например, 3-мерный вектор называется так:

std::vector<std::vector<std::vector<value_type>>>

Не говоря уже о том, хотел бы я иметь 4-мерный или даже больше.

Есть ли способ использовать, возможно, шаблонное метапрограммирование или какой-либо метод, чтобы иметь возможность объявить вектор высокой размерности с более высокой читабельностью?

Например, чтобы иметь возможность объявить вектор высокой размерности, как это (просто пример):

t_vector<5, {10, 2, 2, 2, 2}, int> a;

и получить с емкостью [10] [2] [2] [2] [2].

Возможно ли сделать что-то подобное?Или почему, если нет?

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Вы могли бы использовать typedef, который просто создает псевдоним для типа, например

typedef std::vector<std::vector<std::vector<int>>> iVector3d;

Теперь вы просто используете iVector3d вместо этой большой уродливой вещи, и C ++ буквально заменит iVectord3 фактическим определением, когдавы запускаете код, чтобы ничего не изменилось.

Недостатком этого является то, что вы должны указать тип, как я сделал с int там.Но плюс в том, что он очень прост в использовании по сравнению с шаблонами.

0 голосов
/ 25 октября 2018

Из вашего примера вам нужно std::array вместо std::vector, так как последний не имеет фиксированной длины.

Вы можете просто использовать рекурсию, чтобы специализировать шаблон:

template<class T, size_t... Ns> struct foo;

template<class T, size_t N0, size_t... Ns>
struct foo<T, N0, Ns...> {
    using type = std::array<typename foo<T, Ns...>::type, N0>;
};

template<class T>
struct foo<T> {
    using type = T;
};

template<class T, size_t... Ns>
using multiarray_t = typename foo<T, Ns...>::type;

static_assert(
        std::is_same_v<
            multiarray_t<int, 3, 2, 5>,
            std::array<std::array<std::array<int, 5>, 2>, 3>
            >
        );

РЕДАКТИРОВАТЬ:

Если вы хотите инициировать std::vector с заданным размером, аналогичный подход все еще применяется:

template<class T, size_t... Ns> struct vec_builder;
template<class T, size_t N0, size_t... Ns>
struct vec_builder<T, N0, Ns...> {
    using type = std::vector<
        typename vec_builder<T, Ns...>::type>;
    static type build() {
        return type(N0, vec_builder<T, Ns...>::build());
    }
};
template<class T>
struct vec_builder<T> {
    using type = T;
    static type build() { return {}; }
};

int main() {
    auto vec = vec_builder<int, 3, 2, 5>::build();
    static_assert(
            std::is_same_v<
            decltype(vec),std::vector<std::vector<std::vector<int>>>
            >);
    assert(vec.size() == 3);
    assert(vec[0].size() == 2);
    assert(vec[1][0].size() == 5);
}
...