Контекст:
Я создал общий c контейнер под названием «ComponentManager». Это выглядит примерно так:
typedef uint64_t handle;
template<typename T>
class ComponentManager {
std::vector<T> components; // stores the elements themselves
std::unordered_map<handle, unsigned int> handles; // maps handles to indices
HandleGenerator handleGenerator; // class that generates unique handles
public:
size_t size() const;
handle add(T component); // Adds an element to the component manager, and returns the handle for that element
T* find(handle key) const; // returns a pointer to the element refered to by this handle, or NULL if none exists
void remove(handle key); // may invalidate all iterators. Does NOT invalidate any key (except the one to the element deleted)
ComponentManagerIterator<T> begin();
ComponentManagerIterator<T> end();
};
Этот класс использует ha sh карту дескрипторов -> индексы, чтобы разрешить произвольный доступ O (1) к элементам, а также обеспечить эффективную итерацию по элементам в кэше. из-за их пространственного расположения в векторе (хотя не гарантируется порядок c, поскольку элементы могут перемещаться при удалении элементов)
Проблема:
В существующем виде все дескрипторы в программе имеют один и тот же тип, поэтому пользователь может по ошибке попытаться использовать дескриптор, соответствующий одному диспетчеру дескрипторов, для доступа к элементу в полностью несвязанном диспетчере дескрипторов.
Я хотел бы смягчить это, предоставив сами ручки разного типа, в зависимости от типа handlemanager. Что-то похожее на это:
template<typename T>
class handle
{
public:
uint64_t key;
explicit handle(uint64_t key_) : key(key_) {}
}
Чтобы, если вы попытаетесь использовать дескриптор для неправильного типа handlemanager, код не будет компилироваться без явного приведения.
Однако проблема при этом я все еще иногда хочу рассматривать эти дескрипторы как целые числа. Я бы хотел, чтобы для этого типа были определены все обычные целочисленные операции (сравнение, побитовые операции, et c), и я бы хотел, чтобы алгоритмы, специализированные для целых чисел (например, std :: ha sh), работали так, как если бы мой тип был целым числом. Есть ли способ сделать это, не выполняя вручную каждую из этих операций?
Если есть лучший способ добиться безопасности типов, подобный этому, другим способом, я открыт для других способов достижения этого.
РЕДАКТИРОВАТЬ: Я также должен упомянуть, что в моей программе всегда будет только один диспетчер компонентов для любого заданного типа T, поэтому одного типа будет достаточно, чтобы идентифицировать конкретный c диспетчер компонентов.
РЕДАКТИРОВАТЬ 2 (дополнительный контекст): одно преимущество, которое я вижу в предоставлении уникальных типов дескрипторов, заключается в том, что я могу перегрузить одну функцию для доступа к различным менеджерам компонентов в зависимости от типа дескриптора.