Is it possible to downcast between std::atomic_ref<T> and std::atomic_ref<U> where U is a subclass of T?
I tried the following code which didn't work.
template<typename T>
std::atomic_ref<T> World::getComponentByID(componentInstanceId uuid) const {
static componentTypeId key = stringHash(typeid(T).name());
return components.at(uuid);
}
The template parameter T was position (a subclass of Component). components is a map of componentInstanceIds to Components .
error C2440: 'return': cannot convert from 'const std::atomic_ref<Component>' to 'std::atomic_ref<Position>
CodePudding user response:
Usage of atomic_ref this way does not make sense. (Even in lock_free cases that make sense in assembly language, the ISO C standard doesn't expose that functionality.)
As @Igor Tandetnik pointed out, "No subobject of an object referenced by an atomic_ref object may be concurrently referenced by any other atomic_ref object."
One of reasons this rule exists is that for non-lock-free atomic_ref it implements pool of mutexes, so having sub-object with different pointer value will get you into a different mutex for a subobject, or even a mutex from a different pool, or it may happen that sub-object is lock-free, but the bigger object is lock-based.
Additionally, possible pointer adjustments may defeat alignment, and it is mandatory for value referenced by atomic_ref to respect atomic_ref<T>::required_alignment.
atomic_ref is not a general purpose facility. Perhaps you just need to protect your objects with std::mutex or std::shared_mutex instead.
