Предположим, мне нужно держать некоторые данные, состоящие из n Foo
s, n Bar
с и н Baz
s. Элементы соответствующих индексов связаны между собой, поэтому вы также можете рассматривать эти данные как n триплетов Foo
, Bar and
Baz`. Первое описание данных — это «структура массивов», второе — «массив структур»; Вы можете найти обсуждение из этих двух макетов здесь, на StackOverflow.
Теперь, если мы знаем n во время компиляции, ваши фиджеры довольно легко выражают оба восприятия в C ++.
Массив структур (AoS):
struct {
Foo foo;
Bar bar;
Baz baz;
} aos_form[n];
Структура массивов (SoA):
struct {
Foo foo[n];
Bar bar[n];
Baz baz[n];
} soa_form;
но учтите, что мы уже нарушаем принцип СУХОГО, когда говорим n
три раза. Это значительно усугубляется, если мы теперь хотим динамически распределять память для наших данных — скажем, с std::unique_ptr
s:
Массив структур (AoS):
struct {
Foo foo;
Bar bar;
Baz baz;
} data_tuple_t;
auto aos_form = std::make_unique<data_tuple_t[]>(n);
достаточно разумно, хотя нам, похоже, сейчас нужно определение типа. Но как насчет SoA? Что ж,
Структура массивов (SoA):
struct {
std::unique_ptr<Foo[]> foo;
std::unique_ptr<Bar[]> bar;
std::unique_ptr<Bas[]> baz;
} soa_form = {
std::make_unique<Foo[]>(n),
std::make_unique<Bar[]>(n),
std::make_unique<Baz[]>(n)
}
Теперь это просто ужасно! Мы повторяем 3 разных способа:
Кроме написания специально настроенного класса, что я могу сделать проще и в целом, чтобы сделать Soa FORM «легче для глаз» (и для пальцев)?
Задача ещё не решена.
Других решений пока нет …