I have a quad-/octree data structure. Im storing the children indexes/ptrs of a cell in an array. Each position in the array represents the location of a child with respect to its parent, e.g. in 2D:
// _____________
// | | |
// | 2 | 3 |
// |_____|_____|
// | | |
// | 0 | 1 |
// |_____|_____|
// for each cell, 4 children are always stored in row-major order
std::vector<std::array<Integer,4>> children;
I know that the max number of children is a subset of the values that an Integer
type can represent. Thus I can identify if a cell is missing a child by using a ''magic'' value like -1
for Integer = int
, or std::numeric_limits<unsigned>::max()
for Integer = unsigned
. This is something that std::optional<Integer>
cannot assume.
As far as I understood, this usage of magic values is one of the raison d'être of std::optional
. Still, I'm worried about the performance of std::vector<std::optional<int>>
in inner loops.
So,
Will the performance of
std::vector<std::optional<int>>
be worse than that ofstd::vector<int>
? (I'm already doing the comparison for "non-existent" value).Or, can the implementation of
std::optional
be optimized to offer the same performance as a rawint
? And how?
Mixing std::optional
in the return type of my functions and magic values in my data structure sounds like a very bad idea. I prefer to be consistent and either use one or the other (at least within the same context). Although I could overload the function that performs the comparison with the magic number:
template<T> bool is_valid(const T& t) {
return /* comparison with magic value for t */;
}
for optional types.