У меня есть структура данных quad/octree. Im хранит дочерние индексы /ptrs ячейки в массиве. Каждая позиция в массиве представляет местоположение дочернего элемента относительно его родителя, например. в 2D:
// _____________
// | | |
// | 2 | 3 |
// |_____|_____|
// | | |
// | 0 | 1 |
// |_____|_____|
// for each cell, 4 children are always stored in row-major order
std::vector<std::array<Integer,4>> children;
Я знаю, что максимальное количество детей является подмножеством значений, которые может представлять тип Integer
. Таким образом, я могу определить, отсутствует ли в ячейке дочерний элемент, используя значение '' magic '', например -1
для Integer = int
, или std::numeric_limits<unsigned>::max()
для Integer = unsigned
. Это то, что std::optional<Integer>
не может принять.
Насколько я понял, это использование магических значений является одним из значений raison d'être std::optional
. Тем не менее, я беспокоюсь о производительности std::vector<std::optional<int>>
во внутренних циклах.
Итак,
-
Будет ли производительность
std::vector<std::optional<int>>
хуже, чем уstd::vector<int>
? (Я уже делаю сравнение для "несуществующего" значения). -
Или можно оптимизировать реализацию
std::optional
, чтобы предлагать такую же производительность, как rawint
? И как?
Смешение std::optional
в возвращаемом типе моих функций и магических значений в моей структуре данных звучит как очень плохая идея. Я предпочитаю быть последовательным и использовать один или другой (по крайней мере, в том же контексте). Хотя я могу перегрузить функцию, которая выполняет сравнение с магическим числом:
template<T> bool is_valid(const T& t) {
return /* comparison with magic value for t */;
}
для дополнительных типов.